BZOJ2594: [Wc2006]水管局长数据加强版
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2594
把删边操作当做加边操作逆序做一遍。。
然后LCT维护动态mst。。(我的lct很丑,居然卡时过掉了。。
#include<cstring> #include<iostream> #include<algorithm> #include<cstdio> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define ll long long #define maxn 1500500 struct data{int u,v,w,id,d; }e[maxn]; struct node{int k,x,y,ans,op; }q[100500]; int f[maxn],fa[maxn],val[maxn],mx[maxn],rev[maxn],st[maxn]; int c[maxn][2]; int n,m,Q; using namespace std; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();} return x*f; } bool cmp(data a,data b){ return a.w<b.w; } bool cmp2(data a,data b){ return (a.u<b.u)||(a.u==b.u&&a.v<b.v); } bool cmp3(data a,data b){ return a.id<b.id; } int find(int x,int y){ int l=1,r=m; while (l<=r){ int mid=(l+r)/2; if (e[mid].u<x||((e[mid].u==x)&&(e[mid].v<y))) l=mid+1; else if (e[mid].u==x&&e[mid].v==y) return mid; else r=mid-1; } } int getfa(int x){ if (f[x]==x) return x; return f[x]=getfa(f[x]); } bool isroot(int x){ int y=fa[x]; if ((c[y][0]!=x)&&(c[y][1]!=x)) return 1; return 0; } void Down(int x){ int l=c[x][0],r=c[x][1]; if (rev[x]) { swap(c[x][0],c[x][1]); rev[l]^=1; rev[r]^=1; rev[x]^=1; } } void up(int x){ int l=c[x][0],r=c[x][1]; mx[x]=x; if (val[mx[l]]>val[mx[x]]) mx[x]=mx[l]; if (val[mx[r]]>val[mx[x]]) mx[x]=mx[r]; } void rot(int x){ int y=fa[x],z=fa[y],l=(c[y][1]==x),r=l^1; if (!isroot(y)){ if (c[z][0]==y) c[z][0]=x; else c[z][1]=x; } fa[x]=z; fa[y]=x; fa[c[x][r]]=y; c[y][l]=c[x][r]; c[x][r]=y; up(y); up(x); } void splay(int x){ int top=0; st[++top]=x; for (int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i]; for (int i=top;i;i--) Down(st[i]); while (!isroot(x)){ int y=fa[x],z=fa[y]; if (!isroot(y)){ if ((c[y][0]==x)^(c[z][0]==y)) rot(x); else rot(y); } rot(x); } } void access(int x){ for (int t=0;x;x=fa[x]){ splay(x); c[x][1]=t; up(x); t=x; } } void makeroot(int x){ access(x); splay(x); rev[x]^=1; } void link(int x,int y){ makeroot(x); fa[x]=y; } void cut(int x,int y){ makeroot(x); access(y); splay(y); if (c[y][0]==x) c[y][0]=fa[x]=0; } void split(int x,int y){ makeroot(x); access(y); splay(y); } int main(){ n=read(); m=read(); Q=read(); rep(i,1,m){ e[i].u=read(); e[i].v=read(); e[i].w=read(); if (e[i].u>e[i].v) swap(e[i].u,e[i].v); } sort(e+1,e+1+m,cmp); rep(i,1,m){ e[i].id=i; val[n+i]=e[i].w; mx[n+i]=n+i; } sort(e+1,e+1+m,cmp2); rep(i,1,Q){ q[i].op=read(); q[i].x=read(); q[i].y=read(); if (q[i].x>q[i].y) swap(q[i].x,q[i].y); if (q[i].op==2){ int now=find(q[i].x,q[i].y); q[i].k=e[now].id; e[now].d=1; } } sort(e+1,e+1+m,cmp3); rep(i,1,n) f[i]=i; int sum=0; rep(i,1,m){ if (e[i].d==1) continue; int x=getfa(e[i].u),y=getfa(e[i].v); if (x!=y){ f[x]=y; sum++; link(e[i].u,i+n); link(e[i].v,i+n); if (sum==n-1) break; } } int now=0,k=0; down(i,Q,1){ if (q[i].op==1) {split(q[i].x,q[i].y); q[i].ans=e[mx[q[i].y]-n].w;} else { split(q[i].x,q[i].y); now=mx[q[i].y]-n; k=q[i].k; if (e[now].w>e[k].w){ cut(e[now].u,now+n); cut(e[now].v,now+n); link(e[k].u,k+n); link(e[k].v,k+n); } } } rep(i,1,Q) if (q[i].op==1) printf("%d\n",q[i].ans); return 0; }