• Splay模板


    题目:https://www.luogu.org/problemnew/show/P3391

    主要练习翻转操作;

    有好几个地方的顺序写反了,调了好久好久...

    整体+1,就可以在翻转时使用左端点-1和右端点+1了;

    节点的val是在原数列中的位置,节点所在的树中位置是现在数列的顺序;

    所以输出就是中序遍历,输出val。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int const MAXN=1e5+5;
    int n,m,cnt,root,del_cur,del_pool[MAXN];
    struct N{
        int ch[3],fa,val,rev,size;
    }t[MAXN];
    int newnode()
    {
        if(del_cur)
        {
            int x=del_cur;del_cur--;
            return del_pool[x];
        }
        cnt++;
        return cnt;
    }
    void del(int x)
    {
        del_pool[++del_cur]=x;
        t[x].ch[0]=0;t[x].ch[1]=0;t[x].fa=0;t[x].val=0;
        t[x].rev=0;t[x].size=0;
    }
    void pushup(int x)
    {
        t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+1;
    }
    void pushdown(int x)
    {
        if(t[x].rev)
        {
            t[t[x].ch[0]].rev^=1;
            t[t[x].ch[1]].rev^=1;
            swap(t[x].ch[0],t[x].ch[1]);//(顺序)
            t[x].rev=0;
        }
    }
    void rotate(int x)
    {
        int y=t[x].fa,z=t[y].fa;
        int d=t[y].ch[1]==x;
        t[z].ch[t[z].ch[1]==y]=x;t[x].fa=z;
        t[y].ch[d]=t[x].ch[d^1];t[t[x].ch[d^1]].fa=y;
        t[x].ch[d^1]=y;t[y].fa=x;//与上行顺序不能反 
        pushup(y);pushup(x);//顺序 
    }
    void splay(int x,int goal)
    {
        while(t[x].fa!=goal)//while而非if 
        {
            int y=t[x].fa,z=t[y].fa;
            if(z!=goal)
            {
                if((t[y].ch[0]==x)==(t[z].ch[0]==y))rotate(y);
                else rotate(x);
            }
            rotate(x);
        }
        pushup(x);
        if(!goal)root=x;
    }
    void insert(int v)
    {
        if(!root)
        {
            root=newnode();
            t[root].val=v;t[root].size=1;
            return;
        }
        int x=root;
        while(1)
        {
            int d=t[x].val<v;
            if(!t[x].ch[d])
            {
                int k=newnode();
                t[x].ch[d]=k;t[k].fa=x;
                t[k].val=v;t[k].size=1;
                splay(k,0);//!
                break;
            }
            x=t[x].ch[d];
        }
    }
    int Kth(int k)
    {
        int u=root;
        while(1)
        {
            pushdown(u);
            if(t[t[u].ch[0]].size+1==k)return u;
            if(t[t[u].ch[0]].size+1>k)u=t[u].ch[0];
            else 
            {
                k-=t[t[u].ch[0]].size+1;
                u=t[u].ch[1];//与上行顺序不能反 
            }
        }
    }
    void Rev(int L,int R)
    {
        int l=Kth(L),r=Kth(R+2);
        splay(l,0);splay(r,l);//r,l而非l,r 
        t[t[r].ch[0]].rev^=1;
    }
    void print(int x)
    {
        pushdown(x);
    //    printf("x=%d l=%d r=%d
    ",x,t[x].ch[0],t[x].ch[1]);
        if(t[x].ch[0])print(t[x].ch[0]);
        if(t[x].val>1&&t[x].val<=n+1)printf("%d ",t[x].val-1);
        if(t[x].ch[1])print(t[x].ch[1]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n+2;i++)insert(i);//+1
        for(int i=1,l,r;i<=m;i++)
        {
            scanf("%d%d",&l,&r);
            Rev(l,r);
        }
        print(root);
        return 0;
    }
  • 相关阅读:
    cd /d %~dp0是什么意思啊?
    [转]修改SDI主窗口Title
    版本控制
    (原创)日志处理(修改)
    (转)VC中让CListBox带有复选框
    (转)专业的程序员需要具备的思考能力:写一个程序需要注意多少细节问题
    vue中vcharts的使用
    1. 持续集成 简单介绍
    os.urandom函数用来获取一个指定长度的随机bytes对象
    python 列表中嵌套列表或列表推导式 如果合并成一个list
  • 原文地址:https://www.cnblogs.com/Zinn/p/9034182.html
Copyright © 2020-2023  润新知