BZOJ 1861 SplayTree

https://www.lydsy.com/JudgeOnline/problem.php?id=1861

A simple problem in Splay

May I write the Splay 

it will take me almost two hours

code of AC:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,inf=1<<30;

int l[N],r[N],cnt[N],val[N],A[N],B[N],fa[N];
int tot,root;
void update(int x){
    int L=l[x];int R=r[x];
    cnt[x]=cnt[L]+cnt[R]+1;
}
void rotate(int x,int &k){
    int y=fa[x];int z=fa[y];
    int R=(r[y]==x);
    if(y==k) k=x;
    else{
        if(l[z]==y) l[z]=x;
        else r[z]=x;
    }
    if(R){
        fa[x]=z;fa[y]=x;fa[l[x]]=y;
        r[y]=l[x];
        l[x]=y;
    }else{
        fa[x]=z;fa[y]=x;fa[r[x]]=y;
        l[y]=r[x];
        r[x]=y;
    }
    update(y);
    update(x);
}
void splay(int x,int &k){
    while(x!=k){
        int y=fa[x];int z=fa[y];
        if(y!=k){
            if((l[y]==x)^(l[z]==y)){
                rotate(x,k);
            }else{
                rotate(y,k);
            }
        }
        rotate(x,k);
    }
}
int find(int p,int val){
    int L=l[p],R=r[p];
    if(cnt[L]+1==val) return p;
    if(val<=cnt[L]) return find(L,val);
    else return find(R,val-1-cnt[L]);
}
int Insert(int x){
    val[++tot]=x;
    l[tot]=root;
    fa[root]=tot;
    cnt[tot]=cnt[root]+1;
    root=tot;
}
int main(){
    int n,m;
    cin>>n>>m;
    Insert(inf);
    for(int i=1;i<=n;++i){
        scanf("%d",&A[i]);
        B[A[i]]=i+1;
    }
    for(int i=1;i<=n;++i){
        Insert(A[i]);
    }
    Insert(inf);
    string s;
    int x,y;
    for(int i=1;i<=m;++i){
        cin>>s;
        if(s[0]=='Q'){
            scanf("%d",&x);
            cout<<val[find(root,x+1)]<<endl;  
        }
        if(s[0]=='T'){
            scanf("%d",&x);
            int a=B[x];
            splay(a,root);
            int num=cnt[l[a]];
            int b=find(root,num);
            int c=find(root,num+2);
            splay(b,root);
            splay(c,r[b]);
            int Begin=find(root,2);
            if(Begin==a) continue;
            l[c]=0;

            update(c);update(a);
            splay(Begin,root);
            fa[a]=Begin;
            l[a]=l[Begin];
            fa[l[Begin]]=a;
            l[Begin]=a;
            update(l[a]);
            update(a);
            update(Begin);
        }
        if(s[0]=='A'){
            scanf("%d",&x);
            int y=B[x];
            splay(y,root);
            cout<<cnt[l[y]]-1<<endl;
        }
        if(s[0]=='B'){
            scanf("%d",&x);
            int a=B[x];
            splay(a,root);
            int num=cnt[l[a]];
            int b=find(root,num);
            int c=find(root,num+2);
            splay(b,root);
            splay(c,r[b]);
            int End=find(root,n+1);
            if(End==a) continue;
            l[c]=0;
            update(c);update(a);
            splay(End,root);
            fa[a]=End;
            r[a]=r[End];
            fa[r[End]]=a;
            r[End]=a;
            update(r[a]);
            update(a);
            update(End);
        }
        if(s[0]=='I'){
			scanf("%d%d",&x,&y);
            int a=B[x];
            splay(a,root);
            int num=cnt[l[a]];
            if(y==-1){
                int b=find(root,num);
                swap(B[val[a]],B[val[b]]);
                swap(val[a],val[b]);
            }
            if(y==1){
                int b=find(root,num+2);
                swap(B[val[a]],B[val[b]]);
                swap(val[a],val[b]);   
            }
        }
        // for(int i=2;i<=n+1;++i){
        //     cout<<val[find(root,i)]<<" ";
        // }
        // cout<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/gipsy_danger/article/details/80339394
今日推荐