【HNOI2012】bzoj2733 永无乡

来源:互联网 发布:java 微信 signature 编辑:程序博客网 时间:2024/05/18 00:40

用启发式合并splay维护,复杂度是O(nlogn)

#include<cstdio>#include<algorithm>using namespace std;const int maxn=1000010;int rd(){    int x=0;    char c=getchar();    while (c<'0'||c>'9') c=getchar();    while (c>='0'&&c<='9')    {        x=x*10+c-'0';        c=getchar();    }    return x;}char rdc(){    char c=getchar();    while (c<'A'||c>'Z') c=getchar();    return c;}int fa[maxn],son[maxn][2],size[maxn],val[maxn],n,q;void pause(){}void rot(int u,int fl){    int v=son[u][fl],x=son[v][fl^1],f=fa[u];    if (f) son[f][son[f][1]==u]=v;    fa[v]=f;    son[v][fl^1]=u;    fa[u]=v;    son[u][fl]=x;    if (x) fa[x]=u;    size[u]=size[son[u][0]]+size[son[u][1]]+1;    size[v]=size[son[v][0]]+size[son[v][1]]+1;}void splay(int u){    int x,fx,y,fy;    while (fa[u])    {        x=fa[u];        fx=son[x][1]==u;        if (!fa[x]) rot(x,fx);        else        {            y=fa[x];            fy=son[y][1]==x;            if (fx==fy) rot(y,fy),rot(x,fx);            else rot(x,fx),rot(y,fy);        }    }}void ins(int u,int v){    size[u]++;    if (val[v]<val[u])    {        if (son[u][0]) ins(son[u][0],v);        else        {            son[u][0]=v;            fa[v]=u;        }    }    else    {        if (son[u][1]) ins(son[u][1],v);        else        {            son[u][1]=v;            fa[v]=u;        }    }}int qry(int u,int k){    //printf("%d,%d,%d\n",u,size[u],k);    if (k<=size[son[u][0]]) return qry(son[u][0],k);    if (k==size[son[u][0]]+1) return u;    return qry(son[u][1],k-size[son[u][0]]-1);}void Insert(int r,int u){    if (son[u][0]) Insert(r,son[u][0]);    if (son[u][1]) Insert(r,son[u][1]);    son[u][0]=son[u][1]=0;    size[u]=1;    ins(r,u);    splay(u);}void Join(int u,int v){    if (!u||!v) return;    splay(u);    splay(v);    if (fa[u]) return;    if (size[u]<size[v]) swap(u,v);    Insert(u,v);}int Query(int u,int k){    splay(u);    if (size[u]<k) return -1;    int v=qry(u,k);    splay(v);    return v;}int main(){    //freopen("d.in","r",stdin);    //freopen("bzoj_2733.in","r",stdin);    //freopen("bzoj_2733.out","w",stdout);    int u,v;    char c;    n=rd();    q=rd();    for (int i=1;i<=n;i++) val[i]=rd(),size[i]=1;    while (q--)    {        u=rd();        v=rd();        //if (!q) pause();        Join(u,v);        //if (size[0]) pause();    }    q=rd();    while (q--)    {        c=rdc();        u=rd();        v=rd();        if (c=='B') Join(u,v);        else printf("%d\n",Query(u,v));    }}
原创粉丝点击