zoukankan      html  css  js  c++  java
  • 【BZOJ 3674】可持久化并查集加强版&【BZOJ 3673】可持久化并查集 by zky 用可持久化线段树破之

    最后还是去掉异或顺手A了3673,,,

    并查集其实就是fa数组,我们只需要维护这个fa数组,用可持久化线段树就行啦

    1:判断是否属于同一集合,我加了路径压缩。

    2:直接把跟的值指向root[k]的值破之。

    3:输出判断即可。

    难者不会,会者不难,1h前我还在膜这道题,现在吗hhh就当支持下zky学长出的题了。

    3673:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define read(x) x=getint()
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    using namespace std;
    inline const int getint(){char c=getchar();int k=1,r=0;for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
    const int N=2*1E4+10;
    struct node{int l,r,f;}T[N*100];
    int cnt,root[N],n,m;
    inline void update(int l,int r,int &pos,int x,int fa){
    	T[++cnt]=T[pos]; pos=cnt;
    	if (l==r) {T[pos].f=fa; return;}
    	int mid=(l+r)>>1;
    	if (x<=mid) update(l,mid,T[pos].l,x,fa);
    	else update(mid+1,r,T[pos].r,x,fa);
    }
    inline int ask(int l,int r,int pos,int x){
    	if (l==r) return T[pos].f;
    	int mid=(l+r)>>1;
    	if (x<=mid) return ask(l,mid,T[pos].l,x);
    	else return ask(mid+1,r,T[pos].r,x);
    }
    inline int un(int &rt,int a,int b){
    	update(1,n,rt,a,b);
    	return b;
    }
    inline int find(int &rt,int y){
    	int f=ask(1,n,rt,y);
    	return f==y?y:un(rt,y,find(rt,f));
    }
    int main(){
    	read(n); read(m); int fx,fy,x,y,c;
    	for1(i,1,n) update(1,n,root[0],i,i);
    	for1(i,1,m){
    		read(c);
    		root[i]=root[i-1];
    		switch (c){
    			case 1:
    				read(x); read(y);
    				fx=find(root[i],x),fy=find(root[i],y);
    				if (fx!=fy) un(root[i],fx,fy);
    			break;
    			case 2:
    				root[i]=root[getint()];
    			break;
    			case 3:
    				read(x); read(y);
    				fx=find(root[i],x),fy=find(root[i],y);
    				printf("%d
    ",(fx==fy));
    			break;
    		}
    	}return 0;
    }
    

    3674:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define read(x) x=getint()
    #define for1(i,a,n) for(int i=(a);i<=(n);++i)
    using namespace std;
    inline const int getint(){char c=getchar();int k=1,r=0;for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
    const int N=2*1E5+10;
    struct node{int l,r,f;}T[N*100];
    int cnt,root[N],n,m;
    inline void update(int l,int r,int &pos,int x,int fa){
    	T[++cnt]=T[pos]; pos=cnt;
    	if (l==r) {T[pos].f=fa; return;}
    	int mid=(l+r)>>1;
    	if (x<=mid) update(l,mid,T[pos].l,x,fa);
    	else update(mid+1,r,T[pos].r,x,fa);
    }
    inline int ask(int l,int r,int pos,int x){
    	if (l==r) return T[pos].f;
    	int mid=(l+r)>>1;
    	if (x<=mid) return ask(l,mid,T[pos].l,x);
    	else return ask(mid+1,r,T[pos].r,x);
    }
    inline int un(int &rt,int a,int b){
    	update(1,n,rt,a,b);
    	return b;
    }
    inline int find(int &rt,int y){
    	int f=ask(1,n,rt,y);
    	return f==y?y:un(rt,y,find(rt,f));
    }
    int main(){
    	read(n); read(m); int fx,fy,last=0,x,y,c;
    	for1(i,1,n) update(1,n,root[0],i,i);
    	for1(i,1,m){
    		read(c);
    		root[i]=root[i-1];
    		switch (c){
    			case 1:
    				read(x); read(y); x^=last; y^=last;
    				fx=find(root[i],x),fy=find(root[i],y);
    				if (fx!=fy) un(root[i],fx,fy);
    			break;
    			case 2:
    				root[i]=root[getint()^last];
    			break;
    			case 3:
    				read(x); read(y); x^=last; y^=last;
    				fx=find(root[i],x),fy=find(root[i],y);
    				printf("%d
    ",last=(fx==fy));
    			break;
    		}
    	}return 0;
    }
    

    这样就完了,然而只是达神几年前就随手虐的东西,本蒟蒻必须得努力啊!!!

  • 相关阅读:
    hadoop架构
    hdfs存储模型
    C语言编译过程
    linux文件类型和权限
    推荐系统效果评估
    推荐系统冷启动
    Js计算-当月每周有多少天
    3D动画
    固定边栏——淘宝滚动效果
    jquery图片轮播-插件
  • 原文地址:https://www.cnblogs.com/abclzr/p/5223619.html
Copyright © 2011-2022 走看看