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;
}

 

posted on 2016-01-01 10:32  ctlchild  阅读(144)  评论(0编辑  收藏  举报

导航