• 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
    ",q[i].ans);
        return 0;
    }
  • 相关阅读:
    生物创新科技素养大赛小车代码
    对拍程序
    Link-Cut-Tree学习笔记
    可平面性判定,任意平面图判定(代码实现)
    强联通缩点拓扑排序去重边小技巧
    20200405~06题解
    数论总结
    20200328题解
    Dp优化总结
    20200314题解
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5093056.html
Copyright © 2020-2023  润新知