zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 2816 [ZJOI2012]网络

    Description

    http://www.lydsy.com/JudgeOnline/upload/zjoi2012.pdf

    Solution

    维护树上联通块的信息,支持动态加边删边
    LCT
    总共只有10种颜色,直接建10个LCT,每个LCT维护一种颜色
    LCT还是差不多
    只是第二个操作比较麻烦,得一个一个颜色地去试

    #include<bits/stdc++.h>
    #define ll long long
    #define db double
    #define ld long double
    #define lc(x) ch[(x)][0]
    #define rc(x) ch[(x)][1]
    const int MAXN=10000+10,MAXC=15;
    int n,m,c,k,Val[MAXN],d[MAXC][MAXN];
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    struct LCT{
    	int ch[MAXN][2],fa[MAXN],rev[MAXN],Mx[MAXN];
    	inline void init()
    	{
    		memset(ch,0,sizeof(ch));
    		memset(fa,0,sizeof(fa));
    		memset(rev,0,sizeof(rev));
    		memset(Mx,0,sizeof(Mx));
    	}
    	inline bool nroot(int x)
    	{
    		return lc(fa[x])==x||rc(fa[x])==x;
    	}
    	inline void reverse(int x)
    	{
    		std::swap(lc(x),rc(x));
    		rev[x]^=1;
    	}
    	inline void pushup(int x)
    	{
    		Mx[x]=Val[x];
    		chkmax(Mx[x],Mx[lc(x)]);
    		chkmax(Mx[x],Mx[rc(x)]);
    	}
    	inline void pushdown(int x)
    	{
    		if(rev[x])
    		{
    			if(lc(x))reverse(lc(x));
    			if(rc(x))reverse(rc(x));
    			rev[x]=0;
    		}
    	}
    	inline void rotate(int x)
    	{
    		int f=fa[x],p=fa[f],c=(rc(f)==x);
    		if(nroot(f))ch[p][rc(p)==f]=x;
    		fa[ch[f][c]=ch[x][c^1]]=f;
    		fa[ch[x][c^1]=f]=x;
    		fa[x]=p;
    		pushup(f);
    		pushup(x);
    	}
    	inline void splay(int x)
    	{
    		std::stack<int> s;
    		s.push(x);
    		for(register int i=x;nroot(i);i=fa[i])s.push(fa[i]);
    		while(!s.empty())pushdown(s.top()),s.pop();
    		for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
    			if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
    		pushup(x);
    	}
    	inline void access(int x)
    	{
    		for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y,pushup(x);
    	}
    	inline void makeroot(int x)
    	{
    		access(x);splay(x);reverse(x);
    	}
    	inline int findroot(int x)
    	{
    		access(x);splay(x);
    		while(lc(x))pushdown(x),x=lc(x);
    		splay(x);
    		return x;
    	}
    	inline void split(int x,int y)
    	{
    		makeroot(x);access(y);splay(y);
    	}
    	inline void link(int x,int y)
    	{
    		makeroot(x);
    		if(findroot(y)!=x)fa[x]=y;
    	}
    	inline void cut(int x,int y)
    	{
    		makeroot(x);
    		if(findroot(y)==x&&fa[y]==x&&!lc(y))rc(x)=fa[y]=0,pushup(x);
    	}
    };
    LCT T[MAXC];
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char c='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(c!='')putchar(c);
    }
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    int main()
    {
    	read(n);read(m);read(c);read(k);
    	for(register int i=1;i<=c;++i)T[i].init();
    	for(register int i=1;i<=n;++i)read(Val[i]);
    	for(register int i=1;i<=m;++i)
    	{
    		int u,v,w;
    		read(u);read(v);read(w);
    		w++;
    		d[w][u]++;d[w][v]++;
    		T[w].link(u,v);
    	}
    	while(k--)
    	{
    		int opt;
    		read(opt);
    		if(opt==0)
    		{
    			int x,y;
    			read(x);read(y);
    			Val[x]=y;
    			for(register int i=1;i<=c;++i)T[i].access(x),T[i].splay(x),T[i].pushup(x);
    		}
    		if(opt==1)
    		{
    			int u,v,w,dn=1;
    			read(u);read(v);read(w);
    			w++;
    			for(register int i=1;i<=c;++i)
    				if(T[i].findroot(u)==T[i].findroot(v))
    				{
    					T[i].makeroot(u),T[i].access(v),T[i].splay(v);
    					if(T[i].lc(v)!=u||T[i].rc(u))continue;
    					dn=0;
    					if(i==w)puts("Success.");
    					else if(d[w][u]>=2||d[w][v]>=2)puts("Error 1.");
    					else if(T[w].findroot(u)==T[w].findroot(v))puts("Error 2.");
    					else
    					{
    						T[i].cut(u,v);T[w].link(u,v);
    						d[i][u]--;d[i][v]--;
    						d[w][u]++;d[w][v]++;
    						puts("Success.");
    					}
    					break;
    				}
    			if(dn)puts("No such edge.");
    		}
    		if(opt==2)
    		{
    			int c,u,v;
    			read(c);read(u);read(v);
    			c++;
    			if(T[c].findroot(u)!=T[c].findroot(v))puts("-1");
    			else T[c].split(u,v),write(T[c].Mx[v],'
    ');
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    GTK+ 3.6.2 发布,小的 bug 修复版本
    RunJS 新增 Echo Ajax 测试功能
    Mozilla 发布 Popcorn Maker,在线创作视频
    Sina微博OAuth2框架解密
    Mina状态机State Machine
    Mozilla 发布 Shumway —— 纯JS的SWF解析器
    Code Browser 4.5 发布,代码浏览器
    ROSA 2012 "Enterprise Linux Server" 发布
    ltrace 0.7.0 发布,程序调试工具
    Artifactory 2.6.5 发布,Maven 扩展工具
  • 原文地址:https://www.cnblogs.com/hongyj/p/8687445.html
Copyright © 2011-2022 走看看