zoukankan      html  css  js  c++  java
  • [SDOI2013]森林 主席树 启发式合并

    Code:

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cstring>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define CLR(x,c) memset(x,c,sizeof x)
    int read(){ int a; scanf("%d",&a); return a;}
    
    using namespace std;
    
    void SetIO(string a){
    	string in = a + ".in";
    	freopen(in.c_str(), "r" ,stdin);
    }
    
    const int maxn=80000+5;
    
    int n, m, T;
    
    int val[maxn], Sorted[maxn];
    
    void Discrete(){
    	sort(Sorted + 1, Sorted + 1 + n);
    	for(int i = 1;i <= n; ++i){
    		val[i] = lower_bound(Sorted + 1, Sorted + 1 + n, val[i]) - Sorted;
    	}
    }
    
    int head[maxn], nex[maxn<<1], to[maxn<<1], edges;
    
    void add_edge(int u, int v){
    	nex[++edges] = head[u];
    	head[u] = edges;
    	to[edges] = v;
    }
    
    void Read(){
    	n=read(),n=read(),m=read(), T=read();
    	REP(i,1,n) val[i]=read(), Sorted[i] = val[i];
    
    	REP(i,1,m){
    		int a=read(),b=read();
    		add_edge(a,b);
    		add_edge(b,a);
    	}
    }
    
    const int const_Tree=300;
    
    int root[maxn],numv[maxn*const_Tree];
    
    struct Chair_Tree{
    	int cnt_Tree, lson[maxn*const_Tree], rson[maxn * const_Tree];
    
    	void build(int l,int r,int &o){
    		if(l > r)return;
    		o = ++cnt_Tree;
    		int mid=(l + r) >> 1;
    		build(l, mid, lson[o]);
    		build(mid + 1, r, rson[o]);
    	}
    
    	int insert(int l, int r, int o, int pos){
    		int oo=++cnt_Tree;
    		lson[oo] = lson[o];
    		rson[oo] = rson[o];
    		numv[oo] = numv[o] + 1;
    
    		if(l == r) return oo;
    
    		int mid=(l+r)>>1;	
    		if(pos <= mid) lson[oo] = insert(l,mid,lson[o],pos);
    		else rson[oo] = insert(mid+1,r,rson[o],pos);
    		return oo;
    	}
    
    	int query(int l,int r,int u,int v,int lca,int flca,int k){
    		if(l==r)return l;
    
    		int lsum=numv[lson[u]]+numv[lson[v]]-numv[lson[lca]]-numv[lson[flca]];
    		int mid=(l+r)>>1;
    
    		if(k<=lsum) 
    			return query(l,mid,lson[u],lson[v],lson[lca],lson[flca],k);
    		else 
    			return query(mid+1,r,rson[u],rson[v],rson[lca],rson[flca],k-lsum);
    	}
    
    }Tree;
    
    const int log_Tree = 17;
    
    int dep[maxn], f[log_Tree + 3][maxn],siz[maxn];
    
    int dfs(int u,int fa,int depth){
    	f[0][u]=fa;
    	siz[u]=1;
    	dep[u]=depth;
    	REP(i,1,log_Tree)
    		f[i][u] = f[i-1][f[i-1][u]];	
    
    	root[u]=Tree.insert(1,n,root[fa],val[u]);
    
    	for(int v = head[u];v;v = nex[v]){
    		if(to[v]==fa) continue;
    		siz[u]+=dfs(to[v],u,depth+1);
    	}
    	return siz[u];
    }
    
    void Build(){
    	REP(i,1,n)
    		if(!dep[i]) dfs(i, 0, 1);
    }
    
    int get_lca(int a,int b){
    	if(dep[a] > dep[b]) swap(a,b);
    
    	if(dep[a] != dep[b]){
    		for(int i=log_Tree;i>=0;--i){
    			if(dep[f[i][b]]>=dep[a]) b=f[i][b];
    		}
    	}
    
    	if(a==b)return a;
    
    
    	for(int i=log_Tree;i>=0;--i){
    		if(f[i][a]!=f[i][b]){
    			a=f[i][a];
    			b=f[i][b];
    		}
    	}
    
    	return f[0][a];
    }
    
    void Work(){
    	int lastans=0;
    	REP(i,1,T)
    	{
    		char opt[3];
    		scanf("%s",opt);
    		int u,v,k;
    		u=read(),v=read();
    
    		u^=lastans, v ^= lastans;
    
    		if(opt[0] == 'Q'){
    			k=read();
    			k^=lastans;
    			int lca=get_lca(u,v);
    			int flca=f[0][lca];
    
    			lastans=Tree.query(1,n,root[u],root[v],root[lca],root[flca],k);
    			lastans=Sorted[lastans];
    			printf("%d
    ",lastans);
    		}
    
    		if(opt[0] == 'L'){
    			add_edge(u,v);
    			add_edge(v,u);
    			if(siz[u]>siz[v]){
    				siz[u]+=dfs(v,u,dep[u]+1);
    			}
    			else{
    				siz[v]+=dfs(u,v,dep[v]+1);
    			}
    		}
    	} 
    }
    
    void Init(){
    	Read();
    	Discrete();
    	Build();
    }
    
    int main(){
    	SetIO("input");
    	Init();
    	Work();
    	return 0;
    }
    

      

  • 相关阅读:
    问题:charles开启Charles-Proxy-macOS Proxy 时报错
    通关中级测评师
    20210104 递归
    20201231-3 字符编码转换详解1
    20201231-2 元组
    20201231-1 购物车程序练习实例
    20201230-3 bytes数据类型
    20201230 python数据类型
    20201230 pyc是什么
    20201230-1 网络基础知识
  • 原文地址:https://www.cnblogs.com/guangheli/p/9845068.html
Copyright © 2011-2022 走看看