AC日记——[HNOI2012]永无乡 bzoj 2733

2733

思路:

  启发式合并splay(n*log^2n);

来,上代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define maxn 100001

int n,q,tot,ch[maxn*40][2],key[maxn*40],w[maxn*40],opi[maxn*40],m;
int size[maxn*40],root[maxn],id[maxn*40],f[maxn],cnt,dis[maxn*40],lar[maxn];

inline void in(int &now)
{
    char Cget=getchar();now=0;
    while(Cget>'9'||Cget<'0') Cget=getchar();
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
}

inline int getson(int now)
{
    return ch[opi[now]][1]==now;
}

inline void updata(int now)
{
    size[now]=w[now];
    if(ch[now][0]) size[now]+=size[ch[now][0]];
    if(ch[now][1]) size[now]+=size[ch[now][1]];
}

inline void rotate(int now)
{
    int fa=opi[now],ffa=opi[fa],pos=getson(now);
    ch[fa][pos]=ch[now][pos^1];
    if(ch[fa][pos]) opi[ch[fa][pos]]=fa;
    if(ffa) ch[ffa][getson(fa)]=now;
    ch[now][pos^1]=fa,opi[fa]=now,opi[now]=ffa;
    updata(fa),updata(now);
}

inline void splay(int now,int to)
{
    for(int fa;fa=opi[now];rotate(now))
    {
        if(opi[fa]) rotate(getson(now)==getson(fa)?fa:now);
    }
    root[to]=now;
}

inline void insert(int x,int y,int to)
{
    if(!root[to])
    {
        root[to]=++tot,key[tot]=x,w[tot]=size[tot]=1,id[tot]=y;
        return ;
    }
    int now=root[to],fa=0;
    while(1)
    {
        fa=now;
        if(x<key[now]) now=ch[now][0];
        else now=ch[now][1];
        if(!now)
        {
            now=ch[fa][x>key[fa]]=++tot;
            key[now]=x,id[now]=y,w[now]=size[now]=1,opi[now]=fa;
            splay(now,to);break;
        }
    }
}

inline int find(int x)
{
    if(x==f[x]) return x;
    return f[x]=find(f[x]);
}

inline int irank(int k,int to)
{
    int now=root[to];
    while(1)
    {
        int dis=size[ch[now][0]];
        if(k<=dis) now=ch[now][0];
        else
        {
            k-=dis;
            if(k<=w[now])
            {
                splay(now,to);
                return id[now];
            }
            else k-=w[now],now=ch[now][1];
        }
    }
}

inline void merge(int noww,int now)
{
    if(!now) return ;
    if(ch[now][0]) merge(noww,ch[now][0]);
    insert(key[now],id[now],noww);
    if(ch[now][1]) merge(noww,ch[now][1]);
}

int main()
{
    in(n),in(m);int x,y;char ch[4];
    for(int i=1;i<=n;i++) in(dis[i]),f[i]=i,insert(dis[i],i,i),lar[i]=1;
    for(;m--;)
    {
        in(x),in(y);
        x=find(x),y=find(y);
        if(lar[x]<lar[y]) swap(x,y);lar[x]+=lar[y];
        if(x!=y) f[y]=x,merge(x,root[y]);
    }
    in(q);
    for(;q--;)
    {
        scanf("%s",ch);in(x),in(y);
        if(ch[0]=='Q')
        {
            x=find(x);
            if(y<=size[root[x]]) printf("%d
",irank(y,x));
            else printf("-1
");
        }
        else
        {
            x=find(x),y=find(y);
            if(lar[x]<lar[y]) swap(x,y);lar[x]+=lar[y];
            if(x!=y) f[y]=x,merge(x,root[y]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6826989.html