【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)<<'\n';
		}
	}
}
posted @ 2019-03-20 19:36  Stargazer_cykoi  阅读(106)  评论(0编辑  收藏  举报