bzoj 2733: [HNOI2012]永无乡

来源:互联网 发布:网络映射连接不上 编辑:程序博客网 时间:2024/06/05 00:52

treap启发式合并;

#include<bits/stdc++.h>#define rep(i,k,n) for(int i=k;i<=n;i++)#define ls ch[x][0]#define rs ch[x][1]#define son ch[x][d]using namespace std;const int N=100005;int root[N],p[N],ch[N][2],s[N],val[N],key[N],n,m,tot=0,Q;int find(int x){return p[x]==x ? x : p[x]=find(p[x]);}void up(int x){s[x]=s[ls]+s[rs]+1;}void rotate(int& x,int d){    int y=ch[x][d^1];ch[x][d^1]=ch[y][d];ch[y][d]=x;up(x),x=y;}inline void ins(int&x,int k){    if(!x){x=k;key[x]=rand();ls=rs=0;s[x]=1;return;}    int d=val[k]>val[x];    ins(ch[x][d],k);    if(key[son]<key[x])rotate(x,d^1);    up(x);}inline int kth(int x,int k){    if(s[x]<k)return -1;    int ss=s[ls]+1;    if(k==ss)return x;    if(k<ss)return kth(ls,k);    else return kth(rs,k-ss);}void merge(int x,int& y){    if(!x)return;    merge(ls,y),merge(rs,y);    ins(y,x);}void init(){    rep(i,1,n){p[i]=i,ins(root[i],i);}}void link(int x,int y){    x=find(x);y=find(y);    if(x!=y){        if(s[root[x]]>s[root[y]])swap(x,y);        merge(root[x],root[y]);        p[x]=y;    }}int main(){//freopen("in.in","r",stdin);    scanf("%d%d",&n,&m);int x,y;    rep(i,1,n)scanf("%d",&val[i]);    init();    rep(i,1,m){        scanf("%d%d",&x,&y);link(x,y);    }scanf("%d",&Q);    char ss[20];    while(Q--){        scanf("%s%d%d",ss,&x,&y);        if(ss[0]=='B'){            link(x,y);            }        else printf("%d\n",kth(root[find(x)],y));    }}
0 0