【Luogu】P2173网络(LCT)
这次坑我的是与或的结合顺序……
开十个LCT记录一下即可。以上。
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cctype> #include<map> #define maxn 210050 #define maxc 12 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct Splay{ struct Node{ int e[2],fa,val,maxi,tag; }tree[maxn]; inline int iden(int x){ return x==tree[tree[x].fa].e[1]; } inline void connect(int x,int fa,int how){ tree[x].fa=fa; tree[fa].e[how]=x; } inline bool isroot(int x){ return x!=tree[tree[x].fa].e[0]&&x!=tree[tree[x].fa].e[1]; } inline void update(int x){ tree[x].maxi=max(tree[x].val,max(tree[tree[x].e[0]].maxi,tree[tree[x].e[1]].maxi)); } void reverse(int x){ swap(tree[x].e[0],tree[x].e[1]); tree[x].tag^=1; } void pushdown(int x){ if(tree[x].tag==0) return; tree[x].tag=0; if(tree[x].e[0]) reverse(tree[x].e[0]); if(tree[x].e[1]) reverse(tree[x].e[1]); } void rotate(int x){ int y=tree[x].fa; int r=tree[y].fa; int sony=iden(x); int sonr=iden(y); tree[x].fa=r; if(!isroot(y)) tree[r].e[sonr]=x; int b=tree[x].e[sony^1]; connect(b,y,sony); connect(y,x,sony^1); update(y); } inline void pushto(int x){ if(!isroot(x)) pushto(tree[x].fa); pushdown(x); return; } void splay(int x){ pushto(x); while(!isroot(x)){ int fa=tree[x].fa; if(!isroot(fa)) if(iden(fa)==iden(x)) rotate(fa); else rotate(x); rotate(x); } update(x); } inline void access(int x){ int last=0; while(x){ splay(x); tree[x].e[1]=last; update(x); last=x; x=tree[x].fa; } } inline void makeroot(int x){ access(x); splay(x); reverse(x); } inline int findroot(int x){ access(x); splay(x); while(tree[x].e[0]) x=tree[x].e[0]; return x; } inline void split(int x,int y){ makeroot(x); access(y); splay(y); } inline void link(int x,int y){ split(x,y); tree[x].fa=y; } inline void cut(int x,int y){ split(x,y); if(tree[y].e[0]!=x||tree[x].e[1]) return; tree[x].fa=tree[y].e[0]=0; } }s[maxc]; inline long long calc(long long x,long long y,long long n){ return x*n+y; } map<long long,int>d; int old[maxn]; int sum[maxn][maxc]; int main(){ int n=read(),m=read(),c=read(),e=read(); for(int i=1;i<=n;++i){ int x=read(); for(int j=0;j<=c;++j) s[j].tree[i].val=s[j].tree[i].maxi=x; } for(int i=1;i<=m;++i){ int from=read(),to=read(),col=read(); sum[from][col]++; sum[to][col]++; old[i+n]=col; if(from>to) swap(from,to); d[calc(from,to,n)]=i+n; s[col].link(from,i+n); s[col].link(to,i+n); } for(int i=1;i<=e;++i){ int opt=read(); if(opt==0){ int x=read(),y=read(); for(int j=0;j<=c;++j){ s[j].splay(x); s[j].tree[x].val=y; s[j].update(x); } } else if(opt==1){ int from=read(),to=read(),col=read(); if(from>to) swap(from,to); if(d.count(calc(from,to,n))==0){ printf("No such edge.\n"); continue; } int id=d[calc(from,to,n)]; if(col==old[id]){ printf("Success.\n"); continue; } if(sum[from][col]==2||sum[to][col]==2){ printf("Error 1.\n"); continue; } if(s[col].findroot(from)==s[col].findroot(to)){ printf("Error 2.\n"); continue; } sum[from][old[id]]--; sum[to][old[id]]--; sum[from][col]++; sum[to][col]++; s[old[id]].cut(from,id); s[old[id]].cut(to,id); old[id]=col; s[old[id]].link(from,id); s[old[id]].link(to,id); printf("Success.\n"); } else{ int col=read(),x=read(),y=read(); if(s[col].findroot(x)!=s[col].findroot(y)){ printf("-1\n"); continue; } s[col].split(x,y); //printf("%d %d>>>\n",y,s[col].tree[y].val); printf("%d\n",s[col].tree[y].maxi); } } return 0; }