• BZOJ 3123 [Sdoi2013]森林


    题解:

    启发式合并主席树

    时间复杂度O(nlogn*logn)

    空间复杂度O(nlogn*logn)

    Woc初始的时候也用了启发式合并建图,然后RE成翔了

    一开始算错了空间,下次注意

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    using namespace std;
    const int maxn=100000;
    
    int n,m,TT;
    int a[maxn];
    int lastans=0;
    
    int cntedge=0;
    int head[maxn]={0};
    int to[maxn<<1]={0},nex[maxn<<1]={0};
    void Addedge(int x,int y){
    	nex[++cntedge]=head[x];
    	to[cntedge]=y;
    	head[x]=cntedge;
    }
    
    
    int b[maxn],nn;
    struct PresidentTree{
    	int ls,rs,d;
    }tree[maxn*100];
    int Tsize=0;
    int root[maxn]={0};
    
    void BuildTree(int &now,int l,int r){
    	now=++Tsize;
    	tree[now].d=0;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	BuildTree(tree[now].ls,l,mid);
    	BuildTree(tree[now].rs,mid+1,r);
    }
    
    void Updatapoint(int &now,int l,int r,int pre,int p){
    	now=++Tsize;
    	tree[now]=tree[pre];
    	tree[now].d++;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	if(p<=mid)Updatapoint(tree[now].ls,l,mid,tree[pre].ls,p);
    	else Updatapoint(tree[now].rs,mid+1,r,tree[pre].rs,p);
    }
    int Queryans(int l,int r,int x,int y,int z,int t,int k){
    	if(l==r)return b[l];
    	int lx=tree[x].ls,ly=tree[y].ls,lz=tree[z].ls,lt=tree[t].ls;
    	int d=tree[lx].d+tree[ly].d-tree[lz].d-tree[lt].d;
    	int mid=(l+r)>>1;
    	if(k<=d)return Queryans(l,mid,lx,ly,lz,lt,k);
    	else return Queryans(mid+1,r,tree[x].rs,tree[y].rs,tree[z].rs,tree[t].rs,k-d);
    }
    
    
    
    int f[maxn][20];
    int dep[maxn];
    void Dfs(int x,int fa){
    	dep[x]=dep[fa]+1;
    	f[x][0]=fa;
    	for(int j=1;j<=19;++j){
    		f[x][j]=f[f[x][j-1]][j-1];
    	}
    	Updatapoint(root[x],1,nn,root[fa],a[x]);
    	for(int i=head[x];i;i=nex[i]){
    		if(to[i]==fa)continue;
    		Dfs(to[i],x);
    	}
    }
    
    int Getlca(int u,int v){
    	if(dep[u]<dep[v])swap(u,v);
    	for(int j=19;j>=0;--j){
    		if(dep[f[u][j]]>=dep[v]){
    			u=f[u][j];
    		}
    	}
    	if(u==v)return u;
    	for(int j=19;j>=0;--j){
    		if(f[u][j]!=f[v][j]){
    			u=f[u][j];v=f[v][j];
    		}
    	}
    	return f[u][0];
    }
    
    int Getans(int u,int v,int k){
    	int lca=Getlca(u,v);
    	return Queryans(1,nn,root[u],root[v],root[lca],root[f[lca][0]],k);
    }
    
    int father[maxn];
    int siz[maxn];
    int Getf(int x){
    	if(father[x]==x)return x;
    	return father[x]=Getf(father[x]);
    }
    void Unionn(int x,int y){
    	int fx=Getf(x);
    	int fy=Getf(y);
    	siz[fy]+=siz[fx];
    	father[fx]=fy;
    }
    
    int testcase;
    int main(){
    	scanf("%d",&testcase);
    	scanf("%d%d%d",&n,&m,&TT);
    	for(int i=1;i<=n;++i){
    		scanf("%d",&a[i]);
    		b[i]=a[i];
    	}
    	sort(b+1,b+1+n);
    	nn=unique(b+1,b+1+n)-b-1;
    	for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+nn,a[i])-b;
    	BuildTree(root[0],1,nn);
    	
    	for(int i=1;i<=n;++i){
    		father[i]=i;siz[i]=1;
    	}
    	while(m--){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		Addedge(x,y);
    		Addedge(y,x);
    		Unionn(x,y);
    	}
    	for(int i=1;i<=n;++i){
    		if(!root[i])Dfs(i,0);
    	}
    	
    	while(TT--){
    		char opty=getchar();
    		while(opty!='Q'&&opty!='L')opty=getchar();
    		int x,y,z;
    		scanf("%d%d",&x,&y);
    		x^=lastans;y^=lastans;
    		if(opty=='Q'){
    			scanf("%d",&z);
    			z^=lastans;
    			printf("%d
    ",lastans=Getans(x,y,z));
    		}else{
    			int fx=Getf(x);
    			int fy=Getf(y);
    			Addedge(x,y);
    			Addedge(y,x);
    			if(Getf(x)==Getf(y))exit(0);
    			if(siz[fx]<siz[fy]){
    				Dfs(x,y);
    			}else{
    				Dfs(y,x);
    			}
    			Unionn(x,y);
    		}
    	}
    	return 0;
    }
    

      

    自己还是太辣鸡了
  • 相关阅读:
    使用South时候由于两个相同id的文件引起的问题
    Python os模块
    Ubuntu的关机重启命令知识
    [BUGFIX]__import_pywin32_system_module__
    Django生产环境的部署-Apache-mod_wsgi
    我是如何将linux用在开发环境中的
    php抽奖概率算法
    PHP接收IOS post过来的json数据无法解析的问题
    python apache下出现The _imaging C module is not installed
    php 打印
  • 原文地址:https://www.cnblogs.com/zzyer/p/8502705.html
Copyright © 2020-2023  润新知