bzoj2816: [ZJOI2012]网络
https://www.lydsy.com/JudgeOnline/problem.php?id=2816
相同颜色的边连起来显然是一棵树
注意到颜色种类很少
我们考虑每种颜色维护一颗动态的树 用LCT维护一下就行了
如果把LCT封装起来,注意把存边权最大值的数组也开在里面。
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <map> 5 using namespace std; 6 const int N=200000+10; 7 int v[N/10]; 8 struct edge{ 9 int u,v; 10 bool operator < (const edge&x) const { 11 if(u==x.u) return v<x.v; 12 return u<x.u; 13 } 14 }; 15 16 void read(int &x){ 17 x=0;int f=1;char c=getchar(); 18 while(c<'0'||c>'9'){if(c=='-')f=-f;c=getchar();} 19 while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c-'0');c=getchar();} 20 x*=f; 21 } 22 23 int st[N]; 24 struct LCT{ 25 int ch[N][2],fa[N],d[N],s[N/10]; 26 bool rev[N]; 27 void update(int x){ 28 int l=ch[x][0],r=ch[x][1];s[x]=v[x]; 29 if(l) s[x]=max(s[l],s[x]); 30 if(r) s[x]=max(s[r],s[x]); 31 } 32 void push(int x){ 33 int l=ch[x][0],r=ch[x][1]; 34 if(rev[x]){ 35 rev[x]^=1;rev[l]^=1;rev[r]^=1; 36 swap(ch[x][1],ch[x][0]); 37 } 38 } 39 bool isrt(int x){ 40 return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; 41 } 42 void rotate(int x){ 43 int y=fa[x],z=fa[y],l,r; 44 if(ch[y][0]==x)l=0;else l=1;r=l^1; 45 if(!isrt(y)){ 46 if(ch[z][0]==y) ch[z][0]=x; 47 else ch[z][1]=x; 48 } 49 fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; 50 ch[y][l]=ch[x][r];ch[x][r]=y; 51 update(y);update(x); 52 } 53 void splay(int x){ 54 int top=0;st[++top]=x; 55 for(int i=x;!isrt(i);i=fa[i]) st[++top]=fa[i]; 56 for(int i=top;i;i--) push(st[i]); 57 while(!isrt(x)){ 58 int y=fa[x],z=fa[y]; 59 if(!isrt(y)){ 60 if((ch[y][0]==x)^(ch[z][0]==y)) rotate(x); 61 else rotate(y); 62 } 63 rotate(x); 64 } 65 update(x); 66 } 67 void access(int x){ 68 for(int t=0;x;t=x,x=fa[x]) 69 splay(x),ch[x][1]=t,update(x); 70 } 71 int find(int x){ 72 access(x);splay(x); 73 while(ch[x][0]) x=ch[x][0]; 74 splay(x); 75 return x; 76 } 77 void makert(int x){ 78 access(x);splay(x);rev[x]^=1; 79 } 80 void cut(int x,int y){ 81 d[x]--;d[y]--; 82 makert(x);access(y);splay(y); 83 ch[y][0]=fa[x]=0;update(y); 84 } 85 void link(int x,int y){ 86 d[x]++;d[y]++; 87 makert(x);fa[x]=y; 88 } 89 int query(int x,int y){ 90 makert(x);access(y);splay(y); 91 return s[y]; 92 } 93 }lct[13]; 94 95 map<edge,int>ma; 96 int main(){ 97 int n,m,c,k; 98 read(n);read(m);read(c);read(k); 99 for(int i=1;i<=n;i++) read(v[i]); 100 for(int i=1;i<=m;i++){ 101 int x,y,z; 102 read(x);read(y);read(z); 103 lct[z+1].link(x,y); 104 edge a,b; 105 a.u=x;a.v=y;ma[a]=z+1; 106 b.u=y;b.v=x;ma[b]=z+1; 107 } 108 for(int i=1;i<=k;i++){ 109 int o,x,y,z; 110 read(o); 111 if(o==0){ 112 read(x);read(y); 113 for(int i=1;i<=c;i++) lct[i].access(x),lct[i].splay(x); 114 v[x]=y; 115 for(int i=1;i<=c;i++) lct[i].update(x); 116 } 117 else if(o==1){ 118 read(x);read(y);read(z);++z; 119 edge a;a.u=x;a.v=y; 120 if(ma[a]==0){ 121 printf("No such edge.\n"); 122 continue; 123 } 124 int t=ma[a]; 125 if(z==t){ 126 printf("Success.\n"); 127 continue; 128 } 129 else if(lct[z].d[x]==2||lct[z].d[y]==2){ 130 printf("Error 1.\n"); 131 continue; 132 } 133 else if(lct[z].find(x)==lct[z].find(y)){ 134 printf("Error 2.\n"); 135 continue; 136 } 137 printf("Success.\n"); 138 lct[t].cut(x,y);lct[z].link(x,y); 139 edge b; 140 a.u=x;a.v=y;ma[a]=z; 141 b.u=y;b.v=x;ma[b]=z; 142 } 143 else { 144 read(x);read(y);read(z);++x; 145 if(lct[x].find(y)!=lct[x].find(z)){ 146 printf("-1\n"); 147 continue; 148 } 149 printf("%d\n",lct[x].query(y,z)); 150 } 151 } 152 return 0; 153 } 154