zoukankan      html  css  js  c++  java
  • P3224 [HNOI2012]永无乡

    大致题意

    给一颗(n)个节点带点权图,现在有(m)次操作,操作分为两种:

    • 询问当前与(u)联通的第(k)大权值是哪个

    • 连接两个节点(u,v)

    (n,m≤10^5)

    分析

    并查集+线段树合并

    维护一个并查集,在合并两个节点(u)(v)的时候把它们的线段树也合并起来

    复杂度((n+m)logn)

    (code)

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 100010;
    int fa[MAXN];
    inline int read(){
    	int X=0; bool flag=1; char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
    	while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
    	if(flag) return X;
    	return ~(X-1);
    }
    struct st{
    	int lson,rson,val,pos;
    }tree[MAXN*100];
    int tot,root[MAXN];
    int val[MAXN];
    int n,m;
    void pushup(int node){
    	tree[node].val = tree[tree[node].lson].val+tree[tree[node].rson].val;
    }
    void insert(int &node,int l,int r,int pos,int val,int ind){
    	if(!node) node = ++tot;
    	if(l==r){
    		tree[node].val+=val;
    		tree[node].pos = ind;
    		return;
    	}
    	int mid = (l+r)>>1;
    	if(pos<=mid) insert(tree[node].lson,l,mid,pos,val,ind);
    	else if(pos>mid) insert(tree[node].rson,mid+1,r,pos,val,ind);
    	pushup(node);
    }
    int query(int node,int l,int r,int k){
    	if(!node||tree[node].val<k){
    	  return -1;	
    	} 
    	if(l==r){
    		return tree[node].pos;
    	}
    	int mid =(l+r)>>1;
    	if(k<=tree[tree[node].lson].val) return query(tree[node].lson,l,mid,k);
    	else return query(tree[node].rson,mid+1,r,k-tree[tree[node].lson].val);
    }
    int merge(int node1,int node2,int l,int r){
    	if(!node1) return node2;
    	if(!node2) return node1;
    	if(l==r){
    		if(tree[node2].pos){
    		tree[node1].pos = tree[node2].pos;
    		tree[node1].val += tree[node2].val;
    		}
    		return node1;
    	}
    	int mid =(l+r)>>1;
    	tree[node1].lson = merge(tree[node1].lson,tree[node2].lson,l,mid);
    	tree[node1].rson = merge(tree[node1].rson,tree[node2].rson,mid+1,r);
    	pushup(node1);
    	return node1;
    }
    int find(int x){
    	if(fa[x]==x) return x;
    	return fa[x] = find(fa[x]);
    } 
    int main(){
    	n = read(),m = read();
    	for(int i=1;i<=n;i++){val[i] = read();
    	fa[i] = i;
    	insert(root[i],1,n,val[i],1,i);
    	} 
    	for(int i=1;i<=m;i++) {
    	int u = read(),v = read();
    	int x = find(u),y = find(v);
    	fa[y] = x; 
    	root[x] = merge(root[x],root[y],1,n);
    	}
    	int q = read();
    	for(int i=1;i<=q;i++){
    		char c;
    		cin>>c;
    		int u = read(),v = read();
    		int x = find(u),y = find(v);
    		if(c=='B'){
    			if(x==y) continue;
    			fa[y] = x;
    			root[x] = merge(root[x],root[y],1,n);
    		}
    		else{
    		    cout<<query(root[x],1,n,v)<<endl;
    		}
    	}
    }
    
  • 相关阅读:
    BZOJ 1093: [ZJOI2007]最大半连通子图
    BZOJ 1406: [AHOI2007]密码箱
    BZOJ 1073: [SCOI2007]kshort
    BZOJ 1857: [Scoi2010]传送带
    AC日记——天天爱跑步 洛谷 P1600
    AC日记——[Sdoi2010]粟粟的书架 bzoj 1926
    AC日记——The Shortest Path in Nya Graph hdu 4725
    AC日记——文化之旅 洛谷 P1078
    AC日记——【模板】分块/带修改莫队(数颜色) 洛谷 P1903
    AC日记——大爷的字符串题 洛谷 P3709
  • 原文地址:https://www.cnblogs.com/xcxc82/p/14021761.html
Copyright © 2011-2022 走看看