• POJ 3580 SuperMemo


    题目:http://poj.org/problem?id=3580

    题意:对一个数列进行如下操作

    操作1:对区间内加一个数

    操作2:对区间内进行反转

    操作3:对区间内进行平移 例如:区间内数为2 3 4,平移1次,则为 4 2 3

    操作4:在x后插入一个数

    操作5:删除x

    操作6:求区间内最小值

    操作1,2,4,5,6都是splay的基本操作

    对于操作3 我们可以先对t进行取模 然后将区间内最后t个分离出来,再插入到区间头部

    要实现这个操作,我们只需要先splay将这t个数组成的子树分离,之后再对原树进行splay,再把这个子树插入到区间头部的左子树下就完成了

    //找了好久错,最后发现我把+=写成了=

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    #define lson i<<1
    #define rson i<<1|1
    using namespace std;
    const int N=2e5+5;
    const int inf=0x3f3f3f3f;
    int f[N],ch[N][2],sz[N],key[N],rev[N],add[N],minn[N];
    int a[N];
    int root,tot;
    inline int get(int x)
    {
        return ch[f[x]][1]==x;
    }
    void update(int x)
    {
        if (x==0) return;
        sz[x]=1;
        if (ch[x][0]) sz[x]+=sz[ch[x][0]];
        if (ch[x][1]) sz[x]+=sz[ch[x][1]];
        minn[x]=key[x];
        if (ch[x][0]) minn[x]=min(minn[x],minn[ch[x][0]]);
        if (ch[x][1]) minn[x]=min(minn[x],minn[ch[x][1]]);
    }
    void pushdown(int x)
    {
        if (x==0) return;
        if (add[x])
        {
            if (ch[x][0])
            {
                int now=ch[x][0];
                minn[now]+=add[x];
                key[now]+=add[x];
                add[now]+=add[x];
            }
            if (ch[x][1])
            {
                int now=ch[x][1];
                minn[now]+=add[x];
                key[now]+=add[x];
                add[now]+=add[x];
            }
            add[x]=0;
        }
        if (rev[x])
        {
            if (ch[x][0])
            {
                int now=ch[x][0];
                rev[now]^=1;
                swap(ch[now][0],ch[now][1]);
            }
            if (ch[x][1])
            {
                int now=ch[x][1];
                rev[now]^=1;
                swap(ch[now][0],ch[now][1]);
            }
            rev[x]=0;
        }
    }
    void Rotate(int x)
    {
        pushdown(f[x]);
        pushdown(x);
        int fa=f[x],ff=f[fa],kind=get(x);
        ch[fa][kind]=ch[x][kind^1];f[ch[x][kind^1]]=fa;
        ch[x][kind^1]=fa;f[fa]=x;
        f[x]=ff;
        if (ff)
            ch[ff][ch[ff][1]==fa]=x;
        update(fa);
        update(x);
    }
    void splay(int x,int y)
    {
        for(int fa;(fa=f[x])!=y;Rotate(x))
            if (f[fa]!=y)
                Rotate((get(fa)==get(x))?fa:x);
        if (y==0) root=x;
    }
    int build(int l,int r,int fa)
    {
        if (l>r) return 0;
        int mid=(l+r)>>1;
        int now=++tot;
        f[now]=fa;key[now]=minn[now]=a[mid];rev[now]=add[now]=0;
        ch[now][0]=build(l,mid-1,now);
        ch[now][1]=build(mid+1,r,now);
        update(now);
        return now;
    }
    int Find(int x)
    {
        int now=root;
        while(1)
        {
            pushdown(now);
            if (ch[now][0]&&sz[ch[now][0]]>=x)
                now=ch[now][0];
            else
            {
                x-=sz[ch[now][0]];
                if (x==1) return now;
                x--;
                now=ch[now][1];
            }
        }
    }
    
    void Treaval(int x) {
        if(x) {
            pushdown(x);
            Treaval(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d min=%2d 
    ",x,ch[x][0],ch[x][1],f[x],sz[x],key[x],minn[x]);
            Treaval(ch[x][1]);
        }
    }
    void debug() {printf("%d
    ",root);Treaval(root);}
    
    int main()
    {
        int n,m;
        while(scanf("%d",&n)!=EOF)
        {
            tot=0;
            a[1]=a[n+2]=inf;
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i+1]);
            root=build(1,n+2,0);
            scanf("%d",&m);
            char s[20];
            int x,y,t;
            while(m--)
            {
                scanf("%s",s);
                switch(s[0])
                {
                    case 'A':
                    {
                        scanf("%d%d%d",&x,&y,&t);
                        int aa=Find(x);
                        int bb=Find(y+2);
                        splay(aa,0);
                        splay(bb,aa);
                        int now=ch[ch[root][1]][0];
                        key[now]+=t;
                        minn[now]+=t;
                        add[now]+=t;
                        update(ch[root][1]);
                        update(root);
                        break;
                    }
                    case 'R':
                    {
                        if (s[3]=='E')
                        {
                            scanf("%d%d",&x,&y);
                            int aa=Find(x);
                            int bb=Find(y+2);
                            splay(aa,0);
                            splay(bb,aa);
                            int now=ch[ch[root][1]][0];
                            rev[now]^=1;
                            swap(ch[now][0],ch[now][1]);
                        }
                        else
                        {
                            scanf("%d%d%d",&x,&y,&t);
                            int len=y-x+1;
                            t=(t%len+len)%len;
                            if (t==0) break;
    
                            int aa=Find(y-t+1);
                            int bb=Find(y+2);
                            splay(aa,0);
                            splay(bb,aa);
                            int tem=ch[ch[root][1]][0];
                            ch[ch[root][1]][0]=0;
                            update(ch[root][1]);
                            update(root);
    
                            aa=Find(x);
                            bb=Find(x+1);
                            splay(aa,0);
                            splay(bb,aa);
                            ch[ch[root][1]][0]=tem;
                            f[tem]=ch[root][1];
                            update(ch[root][1]);
                            update(root);
                        }
                        break;
                    }
                    case 'I':
                    {
                        scanf("%d%d",&x,&t);
                        int aa=Find(x+1);
                        int bb=Find(x+2);
                        splay(aa,0);
                        splay(bb,aa);
                        int now=++tot;
                        ch[ch[root][1]][0]=now;
                        f[now]=ch[root][1];
                        key[now]=t;sz[now]=1;
                        minn[now]=t;
                        ch[now][0]=ch[now][1]=rev[now]=add[now]=0;
                        update(ch[root][1]);
                        update(root);
                        break;
                    }
                    case 'D':
                    {
                        scanf("%d",&x);
                        int aa=Find(x);
                        int bb=Find(x+2);
                        splay(aa,0);
                        splay(bb,aa);
                        ch[ch[root][1]][0]=0;
                        update(ch[root][1]);
                        update(root);
                        break;
                    }
                    case 'M':
                    {
                        scanf("%d%d",&x,&y);
                        int aa=Find(x);
                        int bb=Find(y+2);
                        splay(aa,0);
                        splay(bb,aa);
                        int now=ch[ch[root][1]][0];
                        //debug();
                        printf("%d
    ",minn[now]);
                        break;
                    }
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    深入理解Java内存模型(JMM)
    Java基础知识①
    Java自旋锁的几种实现
    ConcurrentHashMap的CAS操作
    Java集合对比总结
    python模块--os模块
    python模块--random
    Datafactory 学习笔记
    Datafactory 实际使用案例
    Oracle三种排名函数使用
  • 原文地址:https://www.cnblogs.com/bk-201/p/7417317.html
Copyright © 2020-2023  润新知