• 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;  
    }  
  • 相关阅读:
    使用Visual Studio .Net 做自己的汉化软件
    给所有的Control加两个属性,实现回车键自动跳转到下一个控件
    数字逗号标记—以前原创(一)
    解决w3wp.exe占用CPU和内存问题
    sql日期函数
    索引的使用总结
    w3wp.exe狂占内存
    w3wp.exe占内存CPU问题 WIN2003 IIS6.0假死现象的分析
    查看Linux系统日志
    linux动态增加LV空间
  • 原文地址:https://www.cnblogs.com/xuanyiming/p/8194461.html
Copyright © 2020-2023  润新知