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.
");
122                 continue;
123             }
124             int t=ma[a];
125             if(z==t){
126                 printf("Success.
");
127                 continue;
128             }
129             else if(lct[z].d[x]==2||lct[z].d[y]==2){
130                 printf("Error 1.
");
131                 continue;
132             }
133             else if(lct[z].find(x)==lct[z].find(y)){
134                 printf("Error 2.
");
135                 continue;
136             }
137             printf("Success.
");
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
");
147                 continue;
148             }
149             printf("%d
",lct[x].query(y,z));
150         }
151     }
152     return 0;
153 }
154 
View Code
原文地址:https://www.cnblogs.com/lyf2/p/9295217.html