hdu4453

题解:

splay模板

删除,翻转等等

代码:

#include<cstdio>  
#include<cstring>  
#include<cmath>  
#include<algorithm>  
using namespace std;  
const int M=200010;  
int root,N,ch[M][2],pre[M],a[M],size[M],key[M],add[M],rev[M],s[M],tot2,tot1;
#define Key_value ch[ch[root][1]][0]  
void NewNode(int &r,int f,int val)  
{  
    if (tot2)r=s[tot2--];  
    else r+=++tot1;  
    ch[r][0]=ch[r][1]=0;  
    pre[r]=f;  
    size[r]=1;  
    key[r]=val;  
    rev[r]=0;  
    add[r]=0;  
}  
void pushup(int r){size[r]=size[ch[r][0]]+size[ch[r][1]]+1;}  
void build(int &x,int l,int r,int f)  
{  
    if (l>r)return;  
    int mid=(l+r)>>1;  
    NewNode(x,f,a[mid]);  
    build(ch[x][0],l,mid-1,x);  
    build(ch[x][1],mid+1,r,x);  
    pushup(x);  
}   
void update_add(int r,int x)  
{  
    if (!r)return;  
    add[r]+=x;  
    key[r]+=x;  
}  
void update_rev(int r)  
{  
    if (!r)return;  
    swap(ch[r][1],ch[r][0]);  
    rev[r]^=1;  
}  
void pushdown(int r)            
{  
    if (add[r])         
     {   
        update_add(ch[r][0],add[r]);  
        update_add(ch[r][1],add[r]);  
        add[r]=0;  
     }  
    if (rev[r])    
     {  
        update_rev(ch[r][0]);  
        update_rev(ch[r][1]);  
        rev[r]=0;  
     }  
}  
void Rotate(int x,int kind)  
{  
    int y=pre[x];  
    pushdown(y);  
    pushdown(x);  
    ch[y][!kind]=ch[x][kind];  
    pre[ch[x][kind]]=y;  
    if (pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;  
    pre[x]=pre[y];  
    ch[x][kind]=y;  
    pre[y]=x;  
    pushup(y);  
}  
void Splay(int r,int goal)  
{  
    pushdown(r);  
    while(pre[r]!=goal)  
     {  
        if (pre[pre[r]]==goal)  
         {  
            pushdown(pre[r]);  
            pushdown(r);  
            Rotate(r,ch[pre[r]][0]==r);  
         }  
        else  
         {  
            pushdown(pre[pre[r]]);  
            pushdown(pre[r]);  
            pushdown(r);  
            int y=pre[r],kind=(ch[pre[y]][0]==y);  
            if (ch[y][kind]==r)  
             {  
                Rotate(r,!kind);  
                Rotate(r,kind);  
             }  
            else  
             {  
                Rotate(y,kind);  
                Rotate(r,kind);  
             }  
         }  
     }  
    pushup(r);  
    if (goal==0)root=r;  
}  
int get_kth(int r,int k)  
{  
    pushdown(r);  
    int t=size[ch[r][0]]+1;  
    if (t==k)return r;  
    if (t>k)return get_kth(ch[r][0],k);  
    else return get_kth(ch[r][1],k-t);  
}  
void change(int &poss,int k)      
{                       
    int pos=get_kth(root,poss);            
    Splay(pos,0);  
    int tmp=size[ch[root][0]]+1;  
    Splay(get_kth(root,1),0);   
    Splay(get_kth(root,tmp),root);  
    tmp=Key_value;  
    Key_value=0;  
    pushup(ch[root][1]);  
    pushup(root);  
    Splay(get_kth(root,size[root]-1),0);  
    Key_value=tmp;  
    pre[Key_value]=ch[root][1];  
    pushup(ch[root][1]);  
    pushup(root);  
    Splay(get_kth(root,1),0);  
    Splay(get_kth(root,k+2),root);  
}  
void Add(int &poss,int k2,int x)  
{  
    change(poss,k2);  
    update_add(Key_value,x);  
    pushup(ch[root][1]);  
    pushup(root);  
    poss=2;  
}  
void Reverse(int &poss,int k1) 
{  
    change(poss,k1);  
    update_rev(Key_value);  
    pushup(ch[root][1]);  
    pushup(root);  
    poss=2;  
}  
void Insert(int &poss,int x)  
{  
    int pos=get_kth(root,poss);  
    Splay(pos,0);  
    Splay(get_kth(root,size[ch[root][0]]+2),root);  
    NewNode(Key_value,ch[root][1],x);  
    pushup(ch[root][1]);  
    pushup(root);  
}  
void erase(int r)  
{  
    if (r)  
     {  
        s[++tot2]=r;  
        erase(ch[r][0]);  
        erase(ch[r][1]);  
     }  
}  
void Delete(int &poss)  
{  
    int pos=get_kth(root,poss);  
    Splay(pos,0);  
    int tmp=size[ch[root][0]]+1;    
    Splay(get_kth(root,tmp-1),0);  
    Splay(get_kth(root,tmp+1),root);  
    erase(Key_value);  
    pre[Key_value]=0;  
    Key_value=0;  
    pushup(ch[root][1]);  
    pushup(root);  
    if (tmp==size[root])poss=2;  
    else poss=tmp;  
}  
void Move(int &poss,int x)  
{  
    int pos=get_kth(root,poss);  
    if (x==1)  
     {  
        Splay(pos,0);  
        int tmp=size[ch[root][0]];  
        if (size[ch[root][0]]==1)tmp=size[root]-1;  
        poss=tmp;  
     }  
    else  
     {  
        Splay(pos,0);  
        int tmp=size[ch[root][0]]+2;  
        if (tmp==size[root])tmp=2;  
        poss=tmp;  
     }  
}  
int Query(int &poss)  
{  
    int pos=get_kth(root,poss);  
    Splay(pos,0);  
    return key[root];  
}  
int main()  
{  
    int n,m,k1,k2,t=1;  
    while(scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF)  
     {  
        N=n;  
        if (n==0&&m==0&&k1==0&&k2==0)break;  
        printf("Case #%d:
",t++);  
        for (int i=1;i<=n;i++)scanf("%d",&a[i]);  
        int poss=2,sum=n;  
        root=tot1=tot2=0;  
        ch[root][0]=ch[root][1]=size[root]=key[root]=add[root]=pre[root]=0;  
        rev[root]=0;  
            NewNode(root,0,-1);  
            NewNode(ch[root][1],root,-1);  
        build(Key_value,1,N,ch[root][1]);  
        pushup(ch[root][1]);  
        pushup(root);  
        for (int i=1;i<=m;i++)  
         {  
            char a[50];  
            scanf("%s",a);  
            if (a[0]=='q')  
             {  
                int res=Query(poss);  
                printf("%d
",res);  
             }  
            else if (a[0]=='r')Reverse(poss,k1);  
            else if (a[0]=='i')  
             {  
                int x;  
                sum+=1;  
                scanf("%d",&x);  
                Insert(poss,x);  
             }  
            else if (a[0]=='d')  
             {  
                sum-=1;  
                Delete(poss);  
             }  
            else if (a[0]=='m')  
             {  
                int x;  
                scanf("%d",&x);  
                if (x==1)  
                 {  
                    if (poss==2)poss=sum+1;  
                    else poss-=1;  
                 }  
                if (x==2)  
                 {  
                    if (poss==sum+1)poss=2;  
                    else poss+=1;  
                 }  
             }  
            else if (a[0]=='a')  
             {  
                int x;  
                scanf("%d",&x);  
                Add(poss,k2,x);  
             }  
         }  
     }  
    return 0;  
}  
原文地址:https://www.cnblogs.com/xuanyiming/p/8194461.html