洛谷3767 膜法 带权并查集+分治
这么一道题折磨了不知道多久。。。
本来一直在撕烤可持久化,题解也没有看懂
思路:
跑出dfs序,则每条边的作用范围都是两段连续区间,放到线段树上就是2logn个区间
全都在线段树上挂好
然后分治,每次往下跑的时候把边加上,往下跑的时候把边删掉(所以不能路径压缩)
(某dalao写了按秩合并,但是没写也能过,题目不卡)
1 #include <bits/stdc++.h> 2 #define MAXN 500000 3 #define mid (l+r>>1) 4 using namespace std; 5 int n,m,top,TIME,X,Y; 6 int beg[MAXN],en[MAXN],ans[MAXN],fir[MAXN],nex[MAXN]; 7 int fa[MAXN], sz[MAXN], d[MAXN], st[MAXN]; 8 vector<int> O[MAXN],out[MAXN]; 9 struct qry 10 { 11 int u,v,cas; 12 }q[MAXN]; 13 int getfa(int x){return x==fa[x]?x:getfa(fa[x]);} 14 int getdep(int x){return x==fa[x]?0:(d[x]+getdep(fa[x]))%5;} 15 bool com(int x,int y) 16 { 17 return (beg[x]<beg[y] || (beg[x]==beg[y] && en[x]<en[y])); 18 } 19 void dfs(int now) 20 { 21 beg[now]=++TIME; 22 for(int i=fir[now];i;i=nex[i]) 23 dfs(i); 24 en[now]=TIME; 25 } 26 void add(int now,int l,int r,int x,int y,int z) 27 { 28 if(l==x&&r==y) 29 { 30 O[now].push_back(z); 31 // printf("%d %d %d\n",z,x,y); 32 return; 33 } 34 if(x<=mid) 35 add(now<<1,l,mid,x,min(mid,y),z); 36 if(y>mid) 37 add(now<<1|1,mid+1,r,max(x,mid+1),y,z); 38 } 39 void work(int now,int l,int r,int x) 40 { 41 if(l==8 && r==8) 42 int e=1; 43 bool ok=1; 44 for(int i=0;i<O[now].size();i++) 45 { 46 qry _q=q[O[now][i]]; 47 if(getfa(_q.u)==getfa(_q.v)) 48 { 49 if((getdep(_q.v)-getdep(_q.u)+5)%5!=_q.cas) 50 { 51 ok=0; 52 break; 53 } 54 } 55 else 56 { 57 X=getfa(_q.u),Y=getfa(_q.v); 58 fa[st[++top]=Y]=X,d[Y]=(_q.cas+getdep(_q.u)-getdep(_q.v)+5)%5; 59 } 60 } 61 if(ok) 62 if(l==r) 63 ans[l]=1; 64 else 65 { 66 work(now<<1,l,mid,top); 67 work(now<<1|1,mid+1,r,top); 68 } 69 while(top>x) 70 fa[st[top]]=st[top],d[st[top]]=0,top--; 71 } 72 int main() 73 { 74 scanf("%d%d",&n,&m); 75 for(int i=1;i<=m;i++) 76 { 77 int tem; 78 scanf("%d%d",&tem,&q[i].cas); 79 nex[i]=fir[tem];fir[tem]=i; 80 if(q[i].cas<=2) 81 scanf("%d%d",&q[i].u,&q[i].v); 82 else 83 scanf("%d",&tem),out[tem].push_back(i); 84 } 85 dfs(0); 86 for(int i=1;i<=m;i++) 87 if(q[i].cas<=2) 88 { 89 sort(out[i].begin(),out[i].end(),com); 90 for(int j=0;j<=out[i].size();j++) 91 { 92 int L=j?en[out[i][j-1]]+1:beg[i]; 93 int R=j<out[i].size()?beg[out[i][j]]-1:en[i]; 94 if(L<=R) 95 { 96 add(1,1,m+1,L,R,i); 97 } 98 } 99 } 100 for(int i=1;i<=n;i++) 101 fa[i]=i; 102 top=0; 103 work(1,1,m+1,0); 104 for(int i=1;i<=m;i++) 105 puts(ans[beg[i]]?"excited":"naive"); 106 return 0; 107 }