zoukankan      html  css  js  c++  java
  • 【BZOJ2816】【洛谷】【ZJOI2012】—网络(LCT)

    BZOJ传送门

    洛咕传送门

    tmtm注意最后要加一个“..
    没注意就奇怪的挂了……

    发现C<10C<10,直接对于每一个颜色暴力维护一颗LCTLCT就可以了

    判断的话应该比较简单,反正连边个人喜欢用一个mapmap来记录
    注意queryquery及时下传信息否则会出错

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    int n,m,C,K,a[N];
    #define lc(u) son[u][0]
    #define rc(u) son[u][1]
    inline void chemx(int &a,int b){
    	a=(a>b)?a:b;
    }
    struct Lct{
    	int q[N],son[N][2],mx[N],fa[N],rev[N];
    	inline bool isrc(int u){
    		return rc(fa[u])==u;
    	}
    	inline bool isrt(int u){
    		if(!fa[u])return 1;
    		return lc(fa[u])!=u&&rc(fa[u])!=u;
    	}
    	inline void pushup(int u){
    		mx[u]=a[u];
    		if(lc(u))chemx(mx[u],mx[lc(u)]);
    		if(rc(u))chemx(mx[u],mx[rc(u)]);
    	}
        inline void pushdown(int u){
            if(!rev[u])return;
            swap(lc(u),rc(u));		
            if(lc(u))rev[lc(u)]^=1;
            if(rc(u))rev[rc(u)]^=1;
            rev[u]=0;
        }
        inline void rotate(int v){
            int u=fa[v],z=fa[u];
            int t=rc(u)==v;
            if(!isrt(u))son[z][rc(z)==u]=v;
            fa[v]=z;
            son[u][t]=son[v][t^1],fa[son[v][t^1]]=u;		
            son[v][t^1]=u,fa[u]=v;
            pushup(u),pushup(v);
        }
        inline void splay(int u){
            q[q[0]=1]=u;
            for(int v=u;!isrt(v);v=fa[v])q[++q[0]]=fa[v];
            for(int i=q[0];i;i--)pushdown(q[i]);
            while(!isrt(u)){
                if(!isrt(fa[u])){
                    if(isrc(u)==isrc(fa[u]))rotate(fa[u]);
                    else rotate(u);
                }
                rotate(u);
            }
            pushup(u);
        }
        inline void access(int u){
            for(int v=0;u;v=u,u=fa[u]){
                splay(u),rc(u)=v;
                if(v)fa[v]=u;
                pushup(u);
            }
        }
        inline int findrt(int u){
            access(u),splay(u);
            while(pushdown(u),lc(u))u=lc(u);
            splay(u);return u;
        }
        inline void makert(int u){
            access(u);
            splay(u);
            rev[u]^=1;
        }
        inline void link(int u,int v){
            makert(u);if(findrt(v)!=u)fa[u]=v;
        }
        inline void cut(int u,int v){
            makert(u),access(v),splay(v);
            lc(v)=fa[u]=0,pushup(v);
        }
    	inline void split(int u,int v){
    		makert(u),access(v),splay(v);
    	}
    	inline int query(int u,int v){
    		if(findrt(u)!=findrt(v))return -1;		
    		split(u,v);
    		return mx[v];
    	}
    }T[10];
    int c[10][N];
    #define pii pair<int,int>
    #define mp make_pair
    map<pii,int> p;
    int main(){
    	n=read(),m=read(),C=read(),K=read();
    	for(int i=1;i<=n;i++){
    		a[i]=read();
    		for(int j=0;j<C;j++)T[j].mx[i]=a[i];
    	}
    	for(int i=1;i<=m;i++){
    		int u=read(),v=read(),w=read();
    		c[w][u]++,c[w][v]++;
    		T[w].link(u,v),p[mp(u,v)]=w+1;
    	}
    	for(int i=1;i<=K;i++){
    		int op=read();
    		if(op==0){
    			int u=read(),k=read();
    			for(int i=0;i<C;i++){
    				T[i].makert(u),a[u]=k;
    				T[i].pushup(u);
    			}
    		}
    		else if(op==1){
    			int u=read(),v=read(),w=read(),pre,k;
    			if(!p[mp(u,v)]&&!p[mp(v,u)]){puts("No such edge.");continue;}
    			if((p[mp(u,v)]&&p[mp(u,v)]==w+1)||(p[mp(v,u)]&&p[mp(v,u)]==w+1)){
    				puts("Success.");continue;
    			}
    			if(p[mp(u,v)])pre=p[mp(u,v)]-1,k=1;else pre=p[mp(v,u)]-1,k=2;
    			if(c[w][u]>=2||c[w][v]>=2){puts("Error 1.");continue;}
    			if(T[w].findrt(v)==T[w].findrt(u)){puts("Error 2.");continue;}
    			c[pre][u]--,c[pre][v]--,T[pre].cut(u,v);
    			if(k==1)p[mp(u,v)]=w+1;else p[mp(v,u)]=w+1;
    			c[w][u]++,c[w][v]++,T[w].link(u,v);puts("Success.");
    		}
    		else{
    			int k=read(),u=read(),v=read();
    			cout<<T[k].query(u,v)<<'
    ';
    		}
    	}
    }
    
  • 相关阅读:
    spring揭秘 读书笔记 六 bean的一生
    分枝限界算法
    libLAS1.8.0 编译和配置(VS2013+Win7 64)(一)
    Unity学习笔记 之 发射小球碰撞物体的代码记录
    hdu1281 棋盘游戏 --- 最大匹配
    javascript设计模式
    3、Android中Activity的跳转
    2.11 确定运行计划
    php扩展之 pdo_mysql.so
    POJ 1061 青蛙的约会(扩展欧几里得)
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145603.html
Copyright © 2011-2022 走看看