2020/8/26
英语四级
学习了kruskal重构树+dfs板的lca
mad dfs的lca竟然会快一点
#include"stdio.h" #include"string.h" #include"stack" #include"map" #include"math.h" #include"iostream" #include"vector" #include"queue" #include"algorithm" using namespace std; #pragma GCC optimize(2) inline int read() { int x = 0; bool f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = 0; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; if (f) return x; return 0 - x; } const int N = 300100; const int mod = 1e9 + 7; typedef struct Node{ int x,y,w; }Node; Node node[N]; int head[N],ver[N << 1],Next[N << 1],Edge[N << 1],tot; int n,m,top; int far[N],w[N]; int A,B,C,P; int k,t; int id[N],d[N]; int f[N][20]; int lg[N]; inline int rnd(){return A=(A*B+C)%P;} inline void add(int x,int y){ ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot; } bool cmp(Node a,Node b){ return a.w < b.w; } inline int Find(int x){ if(!far[x]) return x; return far[x] = Find(far[x]); } /* inline void bfs(int x){ queue<int> Q;Q.push(x); d[x] = 1; while(!Q.empty()){ int x = Q.front(); Q.pop(); for(int i = head[x]; i; i = Next[i]){ int y = ver[i]; if(d[y]) continue; d[y] = d[x] + 1; f[y][0] = x; for(int j = 1; j <= t; j ++) f[y][j] = f[f[y][j - 1]][j - 1]; Q.push(y); } } } inline int lca(int x,int y){ if(d[x] > d[y]) x ^= y ^= x ^= y; for(int i = t; i >= 0; i --) if(d[f[y][i]] >= d[x]) y = f[y][i]; if(x == y) return x; for(int i = t; i >= 0; i --) if(f[x][i] != f[y][i]) x = f[x][i],y = f[y][i]; return f[x][0]; }*/ void dfs(int cur, int fath) { f[cur][0] = fath; d[cur] = d[fath] + 1; for (int i = 1; i <= lg[d[cur]]; ++i) f[cur][i] = f[f[cur][i - 1]][i - 1]; for (int i = head[cur]; i ; i = Next[i]) if (ver[i] != fath) dfs(ver[i], cur); } int lca(int x, int y) { if (d[x] < d[y]) swap(x, y); while (d[x] > d[y]) x = f[x][lg[d[x] - d[y]] - 1]; if (x == y) return x; for (int i = lg[d[x]] - 1; i >= 0; --i) if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; return f[x][0]; } int main(){ n = read(); m = read(); for(int i = 1; i <= m; i ++){ node[i].x = read(); node[i].y = read();node[i].w = read(); } sort(node + 1,node + m + 1,cmp); top = n; for(int i = 1; i <= m; i ++){ int x = node[i].x,y = node[i].y; int fx = Find(x),fy = Find(y); if(fx == fy) continue; w[++ top] = node[i].w; add(top,fx); //add(fx,top); add(top,fy); //add(fy,top); far[fx] = top; far[fy] = top; if(top == 2 * n - 1) break; } for (int i = 1; i < N; ++i) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); dfs(top, 0); int q = read(); A = read(); B = read(); C = read(); P = read(); int s = 0; while(q --){ int u=rnd()%n+1,v=rnd()%n+1; int fa = lca(u,v); if(u != v) s += w[fa]; if(s >= mod) s -= mod; } printf("%d\n",s); } /* 3 1 2 3 2 2 6 */ #include"stdio.h" #include"string.h" #include"stack" #include"map" #include"math.h" #include"iostream" #include"vector" #include"queue" #include"algorithm" using namespace std; typedef pair<int,int> PII; inline int read(){ int s = 0, w = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); } return s * w; } const int N = 300100; int head[N],ver[N << 1],Next[N << 1],Edge[N << 1],tot; int n,m; int visit[N],match[N]; void add(int x,int y){ ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot; } bool dfs(int x){ for(int i = head[x]; i; i = Next[i]){ int y = ver[i]; if(visit[y]) continue; visit[y] = 1; if(!match[y] || dfs(match[y])){ match[y] = x; return true; } } return false; } int main(){ int T = read(); while(T --){ n = read(); m = read(); tot = 0; memset(head,0,sizeof(head)); memset(match,0,sizeof(match)); for(int i = 1; i <= m; i ++){ int x = read(),y = read(); add(x,y + n); } int ans = 0; for(int i = 1; i <= n + n; i ++){ memset(visit,0,sizeof(visit)); if(dfs(i)) ans ++; } //ans /= 2; printf("%d\n",n - ans); } } /* 3 1 2 3 2 2 6 */ #include"stdio.h" #include"string.h" #include"stack" #include"map" #include"math.h" #include"iostream" #include"vector" #include"queue" #include"algorithm" using namespace std; #pragma GCC optimize(2) inline int read() { int x = 0; bool f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = 0; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; if (f) return x; return 0 - x; } const int N = 300100; const int mod = 1e9 + 7; typedef struct Node{ int x,y,w; }Node; Node node[N * 3]; int head[N],ver[N << 1],Next[N << 1],Edge[N << 1],tot; int n,m,top; int far[N],w[N]; int high[N],b[N],len; int k,t; int id[N],d[N]; int f[N][20]; int lg[N]; int root[N << 5],sum[N << 5],lc[N << 5],rc[N << 5],tot1; int son[N][2],num,h[N],tt; inline void add(int x,int y){ ver[++ tot] = y; Next[tot] = head[x]; head[x] = tot; } bool cmp(Node a,Node b){ return a.w < b.w; } inline int Find(int x){ if(!far[x]) return x; return far[x] = Find(far[x]); } void dfs(int cur, int fath) { f[cur][0] = fath; d[cur] = d[fath] + 1; for (int i = 1; i <= lg[d[cur]]; ++i) f[cur][i] = f[f[cur][i - 1]][i - 1]; for (int i = head[cur]; i ; i = Next[i]) if (ver[i] != fath) dfs(ver[i], cur); } void Build_Tree(int &rt,int l,int r){ rt = ++ tot1; sum[rt] = 0; if(l == r) return ; int mid = (l + r) >> 1; Build_Tree(lc[rt],l,mid); Build_Tree(rc[rt],mid + 1,r); } void Update(int pre,int &rt,int l,int r,int v){ rt = ++ tot1; lc[rt] = lc[pre]; rc[rt] = rc[pre]; sum[rt] = sum[pre] + 1; if(l == r) return ; int mid = (l + r) >> 1; if(mid >= v) Update(lc[pre],lc[rt],l,mid,v); else Update(rc[pre],rc[rt],mid + 1,r,v); } int query(int u,int v,int l,int r,int k){ int mid = (l + r) >> 1; int x = sum[rc[v]] - sum[rc[u]]; // printf("v = %d u = %d l = %d r = %d k = %d x = %d\n",v,u,l,r,k,x); if(l == r) { if(k - (sum[v] - sum[u]) == 0) return l; return 0; } if(x >= k) return query(rc[u],rc[v],mid + 1,r,k); else return query(lc[u],lc[v],l,mid,k - x); } void dfs1(int x,int far){ son[x][0] = num; if(head[x] == 0){ son[x][0] = ++ num; int id = lower_bound(b + 1,b + len + 1,high[x]) - b; h[++ tt] = id; return ; } for(int i = head[x]; i; i = Next[i]){ int y = ver[i]; if(far == y) continue; dfs1(y,x); } son[x][1] = num; } int main(){ n = read(); m = read(); int q = read(); for(int i = 1; i <= n; i ++) b[i] = high[i] = read(); sort(b + 1,b + n + 1); len = unique(b + 1,b + n + 1) - b - 1; for(int i = 1; i <= m; i ++){ node[i].x = read(); node[i].y = read();node[i].w = read(); } sort(node + 1,node + m + 1,cmp); top = n; for(int i = 1; i <= m; i ++){ int x = node[i].x,y = node[i].y; int fx = Find(x),fy = Find(y); if(fx == fy) continue; w[++ top] = node[i].w; add(top,fx); //add(fx,top); add(top,fy); //add(fy,top); far[fx] = top; far[fy] = top; if(top == 2 * n - 1) break; } for (int i = 1; i < N; ++i) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); t = (int)(log(top) / log(2)) + 1; dfs(top, 0); dfs1(top,1); Build_Tree(root[0],1,len); // printf("tot1 = %d\n",tot1); for(int i = 1; i <= n; i ++){ // printf("h = %d\n",h[i]); Update(root[i - 1],root[i],1,len,h[i]); } // printf("tot1 = %d\n",tot1); b[0] = -1; while(q --){ int u = read(),x = read(),k = read(); for(int i = 20; i >= 0; i --){ if(f[u][i] && w[f[u][i]] <= x) u = f[u][i]; } if(w[u] == 0){ if(k == 1) printf("%d\n",high[u]); else printf("-1\n"); continue; } // printf("u = %d\n",u); // printf("l = %d r = %d root[l] = %d root[r] = %d\n",son[u][0],son[u][1],root[son[u][0]],root[son[u][1]]); if(son[u][1] - son[u][0] < k) printf("-1\n"); else{ int s = query(root[son[u][0]],root[son[u][1]],1,len,k); printf("%d\n",b[s]); } } } /* 3 1 2 3 2 2 6 */