首页 > 其他 > 详细

[HNOI2012]永无乡 题解

时间:2019-06-12 10:12:53      阅读:93      评论:0      收藏:0      [点我收藏+]

权值线段树+并查集

  对于每一个点先建立一个权值线段树,之后并查集维护/更改连通性。

  不知道权值线段树是啥的戳我

  联通就直接把祖先连起来然后合并线段树

  

技术分享图片
#include<cstdio>
#include<iostream>
using namespace std;
const int N=100005;
int size[N*20],n,m,fa[N],type,q,root[N],w[N],rev[N],ls[N*20],rs[N*20];
int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9)
    {if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9)
    x=x*10+ch-48,ch=getchar();
    return x*f;
}
int findf(int x)
{
    if(x==fa[x])return x;
    fa[x]=findf(fa[x]);
    return fa[x];
}
void add(int &k,int l,int r,int val)
{
    if(!k)k=++type;
    if(l==r)
    {
        size[k]=1;
        return ;
    }
    int mid=l+r>>1;
    if(val<=mid)add(ls[k],l,mid,val);
    else add(rs[k],mid+1,r,val);
    size[k]=size[ls[k]]+size[rs[k]];
}
int merge(int x,int y)
{
    if(!x||!y)return x+y;
    ls[x]=merge(ls[x],ls[y]);
    rs[x]=merge(rs[x],rs[y]);
    size[x]=size[ls[x]]+size[rs[x]];
    return x;
}
int query(int k,int l,int r,int val)
{
    if(l==r)return l;
    int mid=l+r>>1,sz=size[ls[k]];
    if(sz>=val)return query(ls[k],l,mid,val);
    else return query(rs[k],mid+1,r,val-sz);
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)w[i]=read(),fa[i]=i,rev[w[i]]=i;
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        int r1=findf(x),r2=findf(y);
        fa[r1]=r2;
    }
    for(int i=1;i<=n;i++)
    {
        int r=findf(i);
        add(root[r],1,n,w[i]);
    }
    q=read();
    char op[3];
    for(int i=1;i<=q;i++)
    {
        scanf("%s",op);
        int x=read(),y=read();
        if(op[0]==B)
        {
            int r1=findf(x),r2=findf(y);
            if(r1!=r2)
            {
                fa[r2]=r1;
                merge(root[r1],root[r2]);
            }
        }
        else 
        {
            int  r=findf(x);
            if(size[root[r]]<y)puts("-1");
            else 
            {
                r=query(root[r],1,n,y);
                printf("%d\n",rev[r]);
            }
        }
    }
    return 0;
}
View Code

 

[HNOI2012]永无乡 题解

原文:https://www.cnblogs.com/Rorschach-XR/p/11007930.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!