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

    浅谈线段树合并:https://www.cnblogs.com/AKMer/p/10251001.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=2733

    对每个联通块维护一个值域线段树,然后该合并合并该查询查询就好了。

    时间复杂度:(O(nlogn))

    空间复杂度:(O(nlogn))

    代码如下:

    #include <cstdio>
    using namespace std;
    
    const int maxn=1e5+5;
    
    char s[5];
    int n,m,q;
    int fa[maxn],rk[maxn],id[maxn],rt[maxn];
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    int find(int x) {
    	if(fa[x]==x)return x;
    	return fa[x]=find(fa[x]);
    }
    
    struct segment_tree {
    	int tot;
    	int sum[maxn*20],ls[maxn*20],rs[maxn*20];
    
    	void update(int p) {
    		sum[p]=sum[ls[p]]+sum[rs[p]];
    	}
    
    	void change(int &p,int l,int r,int pos) {
    		if(!p)p=++tot;
    		if(l==r) {sum[p]++;return;}
    		int mid=(l+r)>>1;
    		if(pos<=mid)change(ls[p],l,mid,pos);
    		else change(rs[p],mid+1,r,pos);
    		update(p);
    	}
    
    	int query(int p,int l,int r,int rk) {
    		if(l==r)return l;
    		int mid=(l+r)>>1;
    		if(rk<=sum[ls[p]])return query(ls[p],l,mid,rk);
    		else return query(rs[p],mid+1,r,rk-sum[ls[p]]);
    	}
    
    	int merge(int a,int b) {
    		if(!a||!b)return a+b;
    		ls[a]=merge(ls[a],ls[b]);
    		rs[a]=merge(rs[a],rs[b]);
    		update(a);return a;
    	}
    }T;
    
    int main() {
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    		rk[i]=read(),id[rk[i]]=i,fa[i]=i;
    	for(int i=1;i<=m;i++) {
    		int a=find(read()),b=find(read());
    		if(a!=b)fa[a]=b;
    	}q=read();
    	for(int i=1;i<=n;i++) {
    		int a=find(i);
    		T.change(rt[a],1,n,rk[i]);
    	}
    	for(int i=1;i<=q;i++) {
    		scanf("%s",s+1);
    		if(s[1]=='Q') {
    			int a=find(read()),k=read();
    			if(T.sum[rt[a]]<k) puts("-1");
    			else printf("%d
    ",id[T.query(rt[a],1,n,k)]);
    		}
    		else {
    			int a=find(read()),b=find(read());
    			if(a!=b) {
    				fa[a]=b;
    				rt[b]=T.merge(rt[b],rt[a]);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Python 规范
    Hql
    Python
    IIS 日志分析
    NHibernate 知识点整理
    微软开放了.NET 4.5.1的源代码
    自定义消息编码绑定实现
    使用自定义绑定
    WCF安全:通过 扩展实现用户名密码认证
    WCF 几种错误
  • 原文地址:https://www.cnblogs.com/AKMer/p/10252000.html
Copyright © 2011-2022 走看看