zoukankan      html  css  js  c++  java
  • BZOJ 1453 [Wc]Dface双面棋盘

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=100009;
    const int oo=1000000000;
    int dx[5]={0,1,0,0,-1};
    int dy[5]={0,0,-1,1,0};
    
    int n,TT;
    
    int cntedge;
    int fa[maxn]={0},ch[maxn][2]={0},siz[maxn],ky[maxn]={0},mn[maxn]={0},mnp[maxn]={0},rev[maxn]={0};
    inline int son(int x){
    	if(ch[fa[x]][0]==x)return 0;
    	else return 1;
    }
    inline void pushup(int x){
    	mn[x]=ky[x];mnp[x]=x;
    	if(mn[ch[x][0]]<mn[x]){
    		mn[x]=mn[ch[x][0]];
    		mnp[x]=mnp[ch[x][0]];
    	}
    	if(mn[ch[x][1]]<mn[x]){
    		mn[x]=mn[ch[x][1]];
    		mnp[x]=mnp[ch[x][1]];
    	}
    	siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+(ky[x]==oo);
    }
    inline void pushdown(int x){
    	if(rev[x]){
    		rev[ch[x][0]]^=1;
    		rev[ch[x][1]]^=1;
    		rev[x]^=1;
    		swap(ch[x][0],ch[x][1]);
    	}
    }
    inline bool isroot(int x){
    	return (ch[fa[x]][0]!=x)&&(ch[fa[x]][1]!=x);
    }
    void Downfa(int x){
    	if(!isroot(x))Downfa(fa[x]);
    	pushdown(x);
    }
    
    inline void Rotate(int x){
    	int y=fa[x];
    	int z=fa[y];
    	int b=son(x),c=son(y);
    	int a=ch[x][b^1];
    	if(!isroot(y))ch[z][c]=x;
    	fa[x]=z;
    	if(a)fa[a]=y;
    	ch[y][b]=a;
    	fa[y]=x;ch[x][b^1]=y;
    	pushup(y);pushup(x);
    }
    void Splay(int x){
    	Downfa(x);
    	while(!isroot(x)){
    		int y=fa[x];
    		if(isroot(y)){
    			Rotate(x);
    		}else{
    			if(son(x)==son(y)){
    				Rotate(y);Rotate(x);
    			}else{
    				Rotate(x);Rotate(x);
    			}
    		}
    	}
    }
    
    void Acc(int x){
    	for(int t=0;x;t=x,x=fa[x]){
    		Splay(x);ch[x][1]=t;pushup(x);
    	}
    }
    void Makeroot(int x){
    	Acc(x);Splay(x);rev[x]^=1;
    }
    void Lin(int x,int y){
    	Makeroot(x);fa[x]=y;
    }
    void Cut(int x,int y){
    	Makeroot(x);Acc(y);Splay(y);
    	fa[ch[y][0]]=0;ch[y][0]=0;pushup(y);
    }
    int Getroot(int x){
    	Acc(x);Splay(x);
    	while(ch[x][0])x=ch[x][0];
    	return x;
    }
    int GetminEdge(int x,int y){
    	Makeroot(x);Acc(y);Splay(y);
    	return mnp[y];
    }
    
    int p[209][209];
    int OG[209][209];
    int a[209][209];
    int opt[maxn][3];
    int ans[maxn][3];
    int nex[maxn];
    int tong[maxn];
    int nowans;
    
    void MakeLink(int x,int y){
    	int lastest=min(tong[x],tong[y]);
    	if(Getroot(x)!=Getroot(y)){
    //		cout<<x<<' '<<y<<endl;
    		--nowans;++cntedge;
    		mn[cntedge]=ky[cntedge]=lastest;
    		mnp[cntedge]=cntedge;
    		Lin(x,cntedge);Lin(y,cntedge);
    	}else{
    		int tm=GetminEdge(x,y);
    //		cout<<tm<<endl;
    		if(ky[tm]>=lastest)return;
    		Cut(x,tm);Cut(y,tm);
    		++cntedge;
    		mn[cntedge]=ky[cntedge]=lastest;
    		mnp[cntedge]=cntedge;
    //		cout<<x<<' '<<y<<endl;
    		Lin(x,cntedge);Lin(y,cntedge);
    	}
    }
    
    int HaveEdge(int x,int y){
    	if(Getroot(x)!=Getroot(y))return 0;
    	Makeroot(x);Acc(y);
    	Splay(y);
    	int tm=siz[ch[y][0]];
    	Splay(x);
    	int tm2=siz[ch[x][0]];
    	if(tm2==tm-1)return 1;
    	else return 0;
    }
    
    void MakeCut(int x,int y){
    	if(!HaveEdge(x,y))return;
    	Cut(x,y);
    	nowans++;
    }
    
    inline int Isright(int x,int y){
    	if((x<=0)||(y<=0))return 0;
    	if((x>n)||(y>n))return 0;
    	return 1;
    }
    
    void Sol1(){
    	ky[0]=mn[0]=oo;
    	nowans=0;
    	cntedge=n*n;
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			a[i][j]=OG[i][j];
    			if(a[i][j])++nowans;
    		}
    	}
    	for(int i=1;i<=n*n;++i)tong[i]=oo-1;
    	for(int i=1;i<=n*n;++i){
    		siz[i]=1;mn[i]=ky[i]=oo;
    	}
    	for(int i=TT;i>=1;--i){
    		tong[p[opt[i][1]][opt[i][2]]]=i;
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			if(a[i][j]!=1)continue;
    			for(int k=1;k<=2;++k){
    				int x=i+dx[k];
    				int y=j+dy[k];
    				if(!Isright(x,y))continue;
    				if(a[x][y]!=1)continue;
    				MakeLink(p[x][y],p[i][j]);
    			}
    		}
    	}
    	for(int i=1;i<=TT;++i){
    		int x=opt[i][1],y=opt[i][2];
    		if(a[x][y]==0){
    			a[x][y]=1;
    			tong[p[x][y]]=nex[i];
    			++nowans;
    			for(int k=1;k<=4;++k){
    				int xx=x+dx[k];
    				int yy=y+dy[k];
    				if(!Isright(xx,yy))continue;
    				if(!a[xx][yy])continue;
    				MakeLink(p[x][y],p[xx][yy]);
    			}
    		}else{
    			a[x][y]=0;
    			tong[p[x][y]]=nex[i];
    			for(int k=1;k<=4;++k){
    				int xx=x+dx[k];
    				int yy=y+dy[k];
    				if(!Isright(xx,yy))continue;
    				if(!a[xx][yy])continue;
    				MakeCut(p[x][y],p[xx][yy]);
    			}
    			--nowans;
    		}
    		ans[i][1]=nowans;
    	}
    }
    void Sol2(){
    	memset(fa,0,sizeof(fa));
    	memset(ch,0,sizeof(ch));
    	memset(ky,0,sizeof(ky));
    	memset(mn,0,sizeof(mn));
    	memset(mnp,0,sizeof(mnp));
    	memset(rev,0,sizeof(rev));
    	ky[0]=mn[0]=oo;
    	nowans=0;
    	cntedge=n*n;
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			a[i][j]=OG[i][j];
    			if(a[i][j]==0)++nowans;
    		}
    	}
    	for(int i=1;i<=n*n;++i)tong[i]=oo-1;
    	for(int i=1;i<=n*n;++i){
    		siz[i]=1;mn[i]=ky[i]=oo;
    	}
    	for(int i=TT;i>=1;--i){
    		tong[p[opt[i][1]][opt[i][2]]]=i;
    	}
    	
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			if(a[i][j])continue;
    			for(int k=1;k<=2;++k){
    				int x=i+dx[k];
    				int y=j+dy[k];
    				if(!Isright(x,y))continue;
    				if(a[x][y])continue;
    //				cout<<"fucking "<<p[x][y]<<' '<<p[i][j]<<endl;
    				MakeLink(p[x][y],p[i][j]);
    			}
    		}
    	}
    //	cout<<"begin"<<endl;
    	for(int i=1;i<=TT;++i){
    		int x=opt[i][1],y=opt[i][2];
    		if(a[x][y]){
    			a[x][y]=0;
    			tong[p[x][y]]=nex[i];
    			++nowans;
    			for(int k=1;k<=4;++k){
    				int xx=x+dx[k];
    				int yy=y+dy[k];
    				if(!Isright(xx,yy))continue;
    				if(a[xx][yy])continue;
    				MakeLink(p[x][y],p[xx][yy]);
    			}
    		}else{
    			a[x][y]=1;
    			tong[p[x][y]]=nex[i];
    			for(int k=1;k<=4;++k){
    				int xx=x+dx[k];
    				int yy=y+dy[k];
    				if(!Isright(xx,yy))continue;
    				if(a[xx][yy])continue;
    				MakeCut(p[x][y],p[xx][yy]);
    			}
    			--nowans;
    		}
    		ans[i][2]=nowans;
    	}
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int cnt=0,i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			p[i][j]=++cnt;
    		}
    	}
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			scanf("%d",&OG[i][j]);
    		}
    	}
    	scanf("%d",&TT);
    	for(int i=1;i<=TT;++i){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		opt[i][1]=x;opt[i][2]=y;
    		if(tong[p[x][y]])nex[tong[p[x][y]]]=i;
    		tong[p[x][y]]=i;
    	}
    	for(int i=1;i<=TT;++i)if(nex[i]==0)nex[i]=oo-1;
    	
    	Sol1();
    	Sol2();
    	
    	for(int i=1;i<=TT;++i)printf("%d %d
    ",ans[i][1],ans[i][2]);
    	return 0;
    }
    

      

    题解:

    动态图的连通性问题

    离线下来,维护边权为删除时间的最大生成树

    在知乎上看了一篇很好的文章,先留坑,以后补上

    自己还是太辣鸡了
  • 相关阅读:
    Nginx 日志切割-定时(附数据库数据备份)
    安装Nginx
    系统自适应限流
    黑名名单控制-sentinel
    热点参数的流量控制
    流量控制文档说明
    在Linux中输入命令时打错并按了enter
    配置maven环境
    项目层次展示
    寻找cmd的管理员运行
  • 原文地址:https://www.cnblogs.com/zzyer/p/8569039.html
Copyright © 2011-2022 走看看