zoukankan      html  css  js  c++  java
  • bzoj 2733: [HNOI2012]永无乡【并查集+权值线段树】

    bzoj上数组开大会T……
    本来想用set瞎搞的,想了想发现不行
    总之就是并查集,每个点开一个动态开点的权值线段树,然后合并的时候把值并在根上,询问的时候找出在根的线段树里找出k小值,看看这个值属于哪个岛即可

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=100005;
    int n,m,q,f[N],rt[N],tot,rl[N];
    char c[5];
    struct qwe
    {
    	int ls,rs,s;
    }t[10000005];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    int zhao(int x)
    {
    	return f[x]==x?x:f[x]=zhao(f[x]);
    }
    void ud(int ro)
    {
    	t[ro].s=t[t[ro].ls].s+t[t[ro].rs].s;
    }
    void update(int &ro,int l,int r,int p)
    {
    	if(!ro)
    		ro=++tot;
    	if(l==r)
    	{
    		t[ro].s=1;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(p<=mid)
    		update(t[ro].ls,l,mid,p);
    	else
    		update(t[ro].rs,mid+1,r,p);
    	ud(ro);
    }
    void hb(int &ro,int la,int l,int r)
    {
    	if(!la)
    		return;
    	if(!ro)
    	{
    		ro=la;
    		return;
    	}
    	if(l==r)
    	{
    		t[ro].s+=t[la].s;
    		return ;
    	}
    	int mid=(l+r)>>1;
    	hb(t[ro].ls,t[la].ls,l,mid);
    	hb(t[ro].rs,t[la].rs,mid+1,r);
    	ud(ro);
    }
    int ques(int ro,int l,int r,int k)
    {
    	if(l==r)
    		return l;
    	int mid=(l+r)>>1;
    	if(t[ro].ls&&t[t[ro].ls].s>=k)
    		return ques(t[ro].ls,l,mid,k);
    	else
    		return ques(t[ro].rs,mid+1,r,k-t[t[ro].ls].s);
    }
    int main()
    {
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    	{
    		f[i]=i;
    		int x=read();
    		rl[x]=i;
    		update(rt[i],1,n,x);
    	}
    	for(int i=1;i<=m;i++)
    	{
    		int x=read(),y=read(),fx=zhao(x),fy=zhao(y);
    		if(fx!=fy)
    		{
    			f[fy]=fx;
    			hb(rt[fx],rt[fy],1,n);
    		}
    	}
    	q=read();
    	while(q--)
    	{
    		scanf("%s",c);
    		int x=read(),y=read();
    		if(c[0]=='B')
    		{
    			int fx=zhao(x),fy=zhao(y);
    			if(fx!=fy)
    			{
    				f[fy]=fx;
    				hb(rt[fx],rt[fy],1,n);
    			}
    		}
    		else
    		{
    			int fx=zhao(x);
    			if(t[rt[fx]].s<y)
    				puts("-1");
    			else
    				printf("%d
    ",rl[ques(rt[fx],1,n,y)]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    继承---原型式继承
    CSS中可继承的属性
    函数定义相关
    现代密码学(对称密码——第一部分)
    数据结构练习题(1)
    数据结构与算法(线性表)
    数据结构与算法(绪论)
    大英四期中单词复习
    计算机组成原理_verilog学习_实验二答案(原创)
    现代密码学——第2章古典密码学
  • 原文地址:https://www.cnblogs.com/lokiii/p/9695115.html
Copyright © 2011-2022 走看看