马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
角逐效果
估测:60 + 100 + 100 + 0 = 260
实得:5 + 100 + 0 + 0 = 105
rk11
挂大分的一场
题解
A. 江桥的天生树(MST)
标题
分析:
我们思量 差别颜色的点终极肯定是联通的。因此我们可以对于每一种颜色可以先拿出来一个点,跑一遍 K r u s k a l Kruskal Kruskal 算法,然后剩下的点可以选择一个代价最小的点连起来。如许肯定是最优的。必要注意的是由于 图很稠密,因此 K r u s k a l Kruskal Kruskal 算法中对边排序会导致 T L E TLE TLE,因此必要用 P r i m Prim Prim 算法。
P r i m Prim Prim 算法头脑:思量往天生树聚集中加点,每次选 间隔天生树近来的点 参加天生树中,并用它更新别的点到天生树的间隔。
时间复杂度 O ( n 2 ) O(n^2) O(n2)。
CODE:
- #include<bits/stdc++.h>
- #define pb push_back
- using namespace std;
- typedef long long LL;
- typedef pair< int, int > PII;
- const int M = 1e6 + 10;
- const int N = 5005;
- int n, a[N], tot;
- LL p, q, w, h;
- LL W[N][N], Min_val[N], res, dis[N];
- int bin[N], Min_id[N];
- bool vis[N];
- void prim() {
-
-
- memset(dis, 0x3f, sizeof dis);
- vis[1] = 1;
- for(int i = 1; i <= n; i ++ ) {
-
-
- if(!vis[i]) dis[i] = min(dis[i], W[1][i]);
- }
- for(int i = 2; i <= n; i ++ ) {
-
-
- int id = -1, Min = 1e18;
- for(int j = 1; j <= n; j ++ ) {
-
-
- if(!vis[j]) {
-
-
- if(dis[j] < Min) Min = dis[j], id = j;
- }
- }
- res += Min;
- vis[id] = 1;
- for(int j = 1; j <= n; j ++ ) {
-
-
- if(!vis[j]) dis[j] = min(dis[j], W[id][j]);
- }
- }
- }
- int main() {
-
-
- memset(Min_val, 0x3f, sizeof Min_val);
- scanf("%d", &n);
- for(int i = 1; i <= n; i ++ ) {
-
-
- scanf("%d", &a[i]);
- }
- scanf("%lld%lld%lld%lld", &p, &q, &w, &h);
- LL tmp = 0;
- for(int i = 1; i <= n * n; i ++ ) {
-
-
- tmp = (p * tmp % h + q) % h;
- int x, y;
- if(i % n == 0) x = (i / n), y = n;
- else x = (i / n + 1), y = i % n;
- if(y >= x) {
-
-
- W[x][y] = W[y][x] = tmp;
- }
- }
- for(int i = 1; i <= n; i ++ ) {
-
-
- for(int j = 1; j <= n; j ++ ) {
-
-
- if(W[i][j] < Min_val[i]) Min_id[i] = j, Min_val[i] = W[i][j];
- }
- }
- for(int i = 1; i <= n; i ++ ) a[i] --;
- for(int i = 1; i <= n; i ++ ) {
-
-
- if(a[i] > 0)
- res += (1LL * a[i] * Min_val[i]);
- }
- prim();
- cout << res << endl;
- return 0;
- }
复制代码 B. 江桥的神机暗码(AC自动机,ST表)
分析:
套路题。起首我们可以罗列一个右端点,然后求出一个最靠前的左端点更新答案。不难发现固定右端点后长度约短越容易满足限定,具有单调性,因此可以二分。思量怎样查验:一个区间不包罗特殊字符串等价于区间内恣意一个位置为末了都不能在区间里形成特殊字符串。因此我们处置惩罚出每个位置为末了,间隔他近来的左端点,满足左端点到它的区间是一个特殊字符,这个可以在构建 A C AC AC 自动机时处置惩罚。那么查验就是区间中全部位置对应的左端点都小于区间左端点。这个可以利用 S T ST ST 表 O ( 1 ) O(1) O(1) 求出区间最小值。
时间复杂度 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
CODE:
- #include<bits/stdc++.h>
- using namespace std;
- const int N = 1e5 + 10;
- int T, n, m, tot, tr[N][26], fail[N], e[N], L[N], Max[21][N];
- char t[N], str[N];
- void Insert(char *s){
-
- //插入
- int p = 0, len = strlen(s + 1);
- for(int i = 1; i <= len; i++){
-
-
- int c = (int)(s[i] - 'a');
- if(!tr[p][c]) tr[p][c] = ++tot;
- p = tr[p][c];
- }
- e[p] = min(e[p], len);
- }
- queue< int > q;
- void build(){
-
-
- int p
复制代码 |