bzoj 1861

splay裸题嘛...

直接按书的编号顺序建splay,然后维护即可

把移动位置变成插入和删除

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
int ch[80005][2];
int f[80005];
int a[80005];
int siz[80005];
char s[15];
int rot,tot;
int n,m;
void update(int rt)
{
    siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1;
}
void rotate(int x)
{
    int y=f[x],z=f[y],k=(ch[y][1]==x);
    ch[z][ch[z][1]==y]=x,f[x]=z;
    ch[y][k]=ch[x][!k],f[ch[x][!k]]=y;
    ch[x][!k]=y,f[y]=x;
    update(y),update(x);
}
void splay(int x,int ed)
{
    while(f[x]!=ed)
    {
        int y=f[x],z=f[y];
        if(z!=ed)
        {
            if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
            else rotate(y);
        }
        rotate(x);
    }
    if(!ed)rot=x;
}
int buildtree(int l,int r,int fa)
{
    if(l==r){siz[a[l]]=1;f[a[l]]=a[fa];return a[l];}
    int mid=(l+r)>>1;
    f[a[mid]]=a[fa];
    if(l<mid)ch[a[mid]][0]=buildtree(l,mid-1,mid);
    if(r>mid)ch[a[mid]][1]=buildtree(mid+1,r,mid);
    update(a[mid]);
    return a[mid];
}
int get_pre(int x)
{
    splay(x,0);
    int l=ch[x][0];
    while(ch[l][1])l=ch[l][1];
    return l;
}
int get_sub(int x)
{
    splay(x,0);
    int r=ch[x][1];
    while(ch[r][0])r=ch[r][0];
    return r;
}
void del(int l,int r)
{
    splay(l,0),splay(r,l);
    f[ch[r][0]]=0,ch[r][0]=0;
}
void ins(int l,int r,int v)
{
    splay(l,0),splay(r,l);
    ch[r][0]=v,f[v]=r,siz[v]=1;
    update(r),update(l);    
}
void push_top(int x)
{
    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int ffr=n+1,eed=get_sub(ffr);
    ins(ffr,eed,x);
}
void push_down(int x)
{
    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int eed=n+2,ffr=get_pre(eed);
    ins(ffr,eed,x);
}
void push_up(int x)
{
    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int ffr=get_pre(fr);
    ins(ffr,fr,x);
}
void push_back(int x)
{
    int fr=get_pre(x),ed=get_sub(x);
    del(fr,ed);
    int eed=get_sub(ed);
    ins(ed,eed,x);
}
void up_and_down(int x)
{
    int T;
    scanf("%d",&T);
    if(T==-1)push_up(x);
    else if(T==1)push_back(x);
}
void query_sum(int x)
{
    splay(x,0);
    printf("%d\n",siz[ch[x][0]]-1);
}
int query_num(int rt,int k)
{
    if(siz[ch[rt][0]]>=k)return query_num(ch[rt][0],k);
    else if(k>siz[ch[rt][0]]+1)return query_num(ch[rt][1],k-1-siz[ch[rt][0]]);
    else return rt;
}
void Query_num(int x)
{
    printf("%d\n",query_num(rot,x+1));
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=2;i<=n+1;i++)scanf("%d",&a[i]);
    a[1]=n+1,a[n+2]=n+2;
    rot=buildtree(1,n+2,0);
    while(m--)
    {
        int x,T;
        scanf("%s%d",s,&x);
        if(s[0]=='T')push_top(x);
        else if(s[0]=='B')push_down(x);
        else if(s[0]=='I')up_and_down(x);
        else if(s[0]=='A')query_sum(x);
        else Query_num(x);
    }
    return 0;
}

 

posted @ 2019-07-02 13:10  lleozhang  Views(118)  Comments(0Edit  收藏  举报
levels of contents