• BZOJ 2733: [HNOI2012]永无乡


    线段树合并

    #include<cstdio>
    using namespace std;
    int cnt,F[100005],ls[2000005],rs[2000005],ID[2000005],sz[2000005],root[100005];
    char s[15];
    int find(int x){
    	if (F[x]!=x) F[x]=find(F[x]);
    	return F[x];
    }
    void insert(int &t,int l,int r,int x,int y){
    	if (!t) t=++cnt;
    	sz[t]++;
    	if (l==r){
    		ID[t]=y;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if (x<=mid) insert(ls[t],l,mid,x,y);
    	else insert(rs[t],mid+1,r,x,y);
    }
    int query(int t,int l,int r,int K){
    	if (l==r) return ID[t];
    	int mid=(l+r)>>1;
    	if (K<=sz[ls[t]]) return query(ls[t],l,mid,K);
    	else return query(rs[t],mid+1,r,K-sz[ls[t]]);
    }
    int merge(int x,int y){
    	if (!x || !y) return x^y;
    	sz[x]+=sz[y];
    	ls[x]=merge(ls[x],ls[y]);
    	rs[x]=merge(rs[x],rs[y]);
    	return x;
    }
    int main(){
    	int n,m;
    	scanf("%d%d",&n,&m);
    	for (int i=1; i<=n; i++){
    		int x;
    		scanf("%d",&x);
    		insert(root[i],1,n,x,i);
    	}
    	for (int i=1; i<=n; i++) F[i]=i;
    	for (int i=1; i<=m; i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		int fx=find(x),fy=find(y);
    		if (fx!=fy) {
    			F[fy]=fx;
    			root[fx]=merge(root[fx],root[fy]);
    		}
    	}
    	int q;
    	scanf("%d",&q);
    	while (q--){
    		scanf("%s",s);
    		if (s[0]=='Q'){
    			int x,k;
    			scanf("%d%d",&x,&k);
    			int fx=find(x);
    			if (sz[root[fx]]<k) printf("-1
    ");
    			else printf("%d
    ",query(root[fx],1,n,k));
    		}
    		else{
    			int x,y;
    			scanf("%d%d",&x,&y);
    			int fx=find(x),fy=find(y);
    			if (fx!=fy){
    				F[fy]=fx;
    				root[fx]=merge(root[fx],root[fy]);
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    hdu 2001 计算两点的距离
    hdu 2001 计算两点的距离
    hdu 2000 ASCII码排序(c语言)
    hdu 2000 ASCII码排序(c语言)
    1.网页学习-开始学习第一步:
    .net 父窗口线程交给子窗口
    多线程传递多个参数
    not Exists的使用方法
    xml.dom.minidom介绍
    .net之线程控件之间访问
  • 原文地址:https://www.cnblogs.com/silenty/p/9838659.html
Copyright © 2020-2023  润新知