[Luo Gu P2596] [ZJOI2006] bookshelf

Title Description: https://www.luogu.org/problem/P2596

 

Analysis: First, to establish a position splay. For an operation, the rotation x to the root, the the left son of x and the subsequent point is connected to. Similarly to the second operation. For the third operation, when t is 0, unchanged, the point corresponding to the front or rear position of the other exchange in nature. Suppose now that the previous exchange position, the point of rotation to the root, then the precursor of the point-to-left son of the rotation point, to exchange. After the exchange location and empathy. 4.5 For operation, you can look directly.

Details: 1 point when a son becomes another point, you must remember to update this point fa. 2. Each time the operation or switching operation is connected, to remember to update size

 

Attach Code:

#include<cstdio>
#include<iostream>
#include<map>
#include<climits>
using namespace std;

const int MAXN=80005;
int n,m;
int val[MAXN];
struct Node{
    int son[2],fa,size,val;
}node[MAXN];
int root;
int ndnum=0;
int mp[MAXN];

inline int read(){
    int ret=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();}
    return ret*f;
}

int new_node(int val){
    int x=++ndnum;
    node[x].fa=node[x].his[0]=node[x].son[1]=0;
    node[x].size=1;node[x].val=val;
    if(val>0) mp[val]=x;
    return x;
}

void update(int x){
    node[x].size=node[node[x].son[0]].size+node[node[x].son[1]].size+1;
}

int buildtree(int l,int r){
    if(l>r) return 0;
    if(l==r) return new_node(val[l]);
    int mid=(l+r)>>1,x=new_node(val[mid]);
    node[x].son[0]=buildtree(l,mid-1);node[x].son[1]=buildtree(mid+1,r);
    node[node[x].son[0]].fa=x;node[node[x].son[1]].fa=x;
    update(x);
    return x;
}

int check(int x){
    return x==node[node[x].fa].son[1];
}

void rotate(int x){
    int y=node[x].fa,z=node[y].fa,d=check(x),xx=node[x].son[d^1];
    node[y].son[d]=xx;node[xx].fa=y;
    node[z].son[check(y)]=x;node[x].fa=z;
    node[x].son[d^1]=y;node[y].fa=x;
    update(y);update(x);
}

void splay(int x,int to=0){
    while(node[x].fa!=to){
        int y=node[x].fa,z=node[y].fa;
        if(z!=to)
            rotate(check(x)==check(y)?y:x);
        rotate(x);
    }
    if(!to)
        root=x;
}

void move_to_first(int x){
    splay(x);
    if(!node[x].son[0]) return;
    if(!node[x].son[1]){
        swap(node[x].son[0],node[x].son[1]);
        return;
    }
    int lson=node[x].son[0],tmp=node[x].son[1];
    while(node[tmp].son[0]) tmp=node[tmp].son[0];
    node[lson].fa=tmp;node[tmp].son[0]=lson;node[x].son[0]=0;
    splay(lson);  
}

void move_to_last(int x){
    splay(x);
    if(!node[x].son[1]) return;
    if(!node[x].son[0]){
        swap(node[x].son[0],node[x].son[1]);
        return;
    }
    int rson=node[x].son[1],tmp=node[x].son[0];
    while(node[tmp].son[1]) tmp=node[tmp].son[1];
    node[rson].fa=tmp;node[tmp].son[1]=rson;node[x].son[1]=0;
    splay(rson);
}

void change(int x,int y){
    splay(x);
    if(y==-1){
        int lson=node[x].son[0];
        if(!lson) return;    
        while(node[lson].son[1]) lson=node[lson].son[1];
        splay(lson,x);
        int lson_lson=node[lson].son[0],lson_rson=node[lson].son[1];
        node[lson].son[0]=x;node[x].fa=lson;
        node[lson].son[1]=node[x].son[1];node[node[x].son[1]].fa=lson;
        node[x].son[0]=lson_lson;node[lson_lson].fa=x;
        node[x].son[1]=lson_rson;node[lson_rson].fa=x;
        node[lson].fa=0;
        update(x);update(lson);
        root=lson;
    } 
    if(y==1){
        int= Node Rson [X] .Son [ 1 ];
         If (Rson!) Return ;
         While (Node [Rson] .Son [ 0 ]) Rson = Node [Rson] .Son [ 0 ]; 
        Splay (Rson, X); 
        int Rson_lson = node [Rson] .Son [ 0 ], Rson_rson = node [Rson] .Son [ 1 ]; 
        node [Rson] .Son [ 0 ] = node [x] .Son [ 0 ]; node [node [x ] .Son [ 0 ]] fa =. Rson; 
        node [Rson] .Son [ 1 ] = x; node [x] .Fa = Rson; 
        node [x] .Son [ 0 ] = Rson_lson; node [Rson_lson]. = Fa X; 
        Node [X] .Son [1]=rson_rson;node[rson_rson].fa=x;
        node[rson].fa=0;
        update(x);update(rson);
        root=rson;
    }
}

int query(int x){
    splay(x);
    return node[node[x].son[0]].size;
}

int find(int kth){
    int cur=root;
    while(1){
        if(kth<=node[node[cur].son[0]].size)
            cur=node[cur].son[0];
        else{
            kth-=node[node[cur].son[0]].size+1;
            if(!kth) return cur;
            cur=node[cur].son[1];
        }
    }
}

void write(int x){
    if(node[x].son[0]) write(node[x].son[0]);
    cout<<node[x].val<<' ';
    if(node[x].son[1]) write(node[x].son[1]);
}

int main(){
    n=read();m=read();
    for(int i=1;i<=n;++i) val[i]=read();
    root=buildtree(1,n);
    while(m--){
        char opt[15];
        scanf("%s",opt+1);
        if(opt[1]=='T'){
            int x=read();
            move_to_first(mp[x]);
        }
        else if(opt[1]=='B'){
            int x=read();
            move_to_last(mp[x]);
        }
        else if(opt[1]=='I'){
            int x=read(),y=read();
            if(y==0) continue;
            change(mp[x],y);
        }
        else if(opt[1]=='A'){
            int x=read();
            printf("%d\n",query(mp[x]));
        }
        else{
            int x=read();
            printf("%d\n",node[find(x)].val);
        }
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/JoshDun/p/11260904.html