• BZOJ2816 [ZJOI2012]网络


    BZOJ2816 [ZJOI2012]网络


    题面描述

    传送门

    题目分析

    首先可以发现这题,如果边都是一个颜色,那么(1)操作就啥用都没有了,就变成了一个裸的树链剖分。。。或者我们也可以用lct来实现这个过程。那么我们又发现这个颜色种类确实不多啊,我们完全可以在(O(mlognC))的时间复杂度内通过。于是我们可以考虑对于每一种颜色都建立一棵lct,然后更改边的颜色的时候,就断掉原来颜色lct上的边,在更改的颜色的lct上连边。

    那么对于(0)操作,暴力修改所有lct就可以了。

    对于(1)那几个鬼畜的输出,可以考虑用一个map来记录是否有边相连。然后对于连通性的判断可以用findroot操作实现。

    是代码呢

    #include <bits/stdc++.h>
    using namespace std;
    #define m_p(x,y) make_pair(x,y)
    const int MAXN=1e4+7;
    int color[MAXN][15],n,m,c,q,v[MAXN];
    map< pair<int,int>,int > mp;
    #define lc ch[x][0]
    #define rc ch[x][1]
    inline int read()
    {
    	int x=0,c=1;
    	char ch=' ';
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	while(ch=='-')c*=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    	return x*c;
    }
    struct lct{
    	int ch[MAXN][2],f[MAXN],mx[MAXN],r[MAXN],st[MAXN];
    	inline bool nroot(int x){return ch[f[x]][0]==x||ch[f[x]][1]==x;}
    	inline void pushr(int x){swap(lc,rc);r[x]^=1;}
    	inline void pushup(int x){mx[x]=max(v[x],max(mx[lc],mx[rc]));}
    	inline void pushdown(int x){
    		if(r[x]){
    			if(lc) pushr(lc);
    			if(rc) pushr(rc);
    			r[x]=0;
    		}
    	}
    	inline void rotate(int x){
    		int y=f[x],z=f[y],kind=ch[y][1]==x,w=ch[x][!kind];
    		if(nroot(y)) ch[z][ch[z][1]==y]=x;ch[x][!kind]=y;ch[y][kind]=w;
    		if(w) f[w]=y;f[f[y]=x]=z;
    		pushup(y);
    	}
    	inline void splay(int x){
    		int y=x,z=0;
    		st[++z]=y;
    		while(nroot(y)) st[++z]=y=f[y];
    		while(z) pushdown(st[z--]);
    		while(nroot(x)){
    			y=f[x],z=f[y];
    			if(nroot(y)) rotate((ch[y][0]==x)^(ch[z][0]==y)?x:y);
    			rotate(x);
    		}
    		pushup(x);
    	}
    	inline void access(int x){
    		for(int y=0;x;x=f[y=x])
    			splay(x),rc=y,pushup(x);
    	}
    	inline void makeroot(int x){
    		access(x);splay(x);pushr(x);
    	}
    	inline void split(int x,int y){
    		makeroot(x);access(y);splay(y);
    	}
    	inline int findroot(int x){
    		access(x);splay(x);
    		while(lc) pushdown(x),x=lc;
    		splay(x);
    		return x;
    	}
    	inline void link(int x,int y){
    		makeroot(x);
    		if(findroot(y)!=x) f[x]=y;
    	}
    	inline void cut(int x,int y){
    		makeroot(x);
    		if(findroot(y)==x&&f[y]==x&&!ch[y][0]){
    			f[y]=ch[x][1]=0;
    			pushup(x);
    		}
    	}
    }LCT[13];
    int main()
    {
    	n=read();m=read();c=read();q=read();
    	for(int i=1;i<=n;i++) v[i]=read();
    	for(int i=1;i<=m;i++) {
    		int x=read(),y=read(),col=read()+1;
    		if(x>y) swap(x,y);
    		mp[m_p(x,y)]=col;
    		color[x][col]++;
    		color[y][col]++;
    		LCT[col].link(x,y);
    	}
    	
    	while(q--){
    		int fl=read();
    		if(fl==0){
    			int x=read(),y=read();
    			for(int i=1;i<=c;i++) LCT[i].splay(x);
    			v[x]=y;
    			for(int i=1;i<=c;i++) LCT[i].pushup(x);
    		} else if(fl==1){
    			int x=read(),y=read(),col2=read()+1;
    			if(x>y) swap(x,y);
    			int col1=mp[m_p(x,y)];
    			if(col1==0){
    				puts("No such edge.");
    				continue;
    			}
    			if(col1==col2){
    				puts("Success.");
    				continue;
    			}
    			if(color[x][col2]==2||color[y][col2]==2){
    				puts("Error 1.");
    				continue;
    			}
    			if(LCT[col2].findroot(x)==LCT[col2].findroot(y)){
    				puts("Error 2.");
    				continue;
    			}
    			puts("Success.");
    			LCT[col1].cut(x,y); 
    			mp[m_p(x,y)]=col2;
    			color[x][col1]--;color[y][col1]--;
    			color[x][col2]++;color[y][col2]++;
    			LCT[col2].link(x,y);
    		} else {
    			int col=read()+1,x=read(),y=read();
    			if(LCT[col].findroot(x)!=LCT[col].findroot(y)) puts("-1");
    			else {
    				LCT[col].split(x,y);
    				printf("%d
    ", LCT[col].mx[y]);
    			}
    		}
    	}
    }
    
  • 相关阅读:
    坑爹的PostgreSQL的美元符号(有时需要替换成单引号)
    DataFrame的apply用法
    Pytorch写CNN
    Pytorch分类和准确性评估--基于FashionMNIST数据集
    设置Mac终端、pip、Anaconda、PyCharm共用一套环境
    Python编程基本规范
    【转】动态规划:最长递增子序列Longest Increasing Subsequence
    动态规划--找零钱
    在线编写复杂的数学公式--EdrawMath
    pandas如何逐行需改DataFrame
  • 原文地址:https://www.cnblogs.com/victorique/p/10237079.html
Copyright © 2020-2023  润新知