• luogu3391


    P3391 【模板】文艺平衡树(Splay)

    题目背景

    这是一道经典的Splay模板题——文艺平衡树。

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

    Input

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
    接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

    Output

    输出一行n个数字,表示原始序列经过m次变换后的结果 

    Sample Input

    5 3
    1 3
    1 3
    1 4

    Sample Output

    4 3 2 1 5

    HINT

    N,M<=100000

    sol:闲的蛋疼打了一遍splay板子,还挂了一发。Ps:注意下传Rev标记

    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0');    return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=100005,inf=0x3f3f3f3f;
    int n,m;
    namespace Pht
    {
        int Points=0,Root;
        int Child[N][2],Parent[N];
        int Size[N];
        int Quanzhi[N];
        bool Rev[N];
    
        inline void Init();
        inline int Check(int x);
        inline void PushUp(int x);
        inline void PushDown(int x);
        inline void Rotate(int x);
        inline void Splay(int At,int To);
        inline void Insert(int Val);
        inline int Ask_Kth(int Id);
        inline void Reverse(int l,int r);
        inline void Output(int Now);
        inline void Solve();
        
        inline void Init()
        {
            int i;
            Insert(-inf);
            for(i=1;i<=n;i++) Insert(i);
            Insert(inf);
        }
        inline int Check(int x)
        {
            return (Child[Parent[x]][0]==x)?0:1;
        }
        inline void PushUp(int x)
        {
            Size[x]=Size[Child[x][0]]+Size[Child[x][1]]+1;
        }
        inline void PushDown(int x)
        {
            if(!Rev[x]) return;
            swap(Child[x][0],Child[x][1]);
            Rev[x]=0;
            Rev[Child[x][0]]^=1;
            Rev[Child[x][1]]^=1;
        }
        inline void Rotate(int x)
        {
            int y,z,oo;
            y=Parent[x];
            z=Parent[y];
            oo=Check(x);
            Child[y][oo]=Child[x][oo^1]; Parent[Child[x][oo^1]]=y;
            Child[z][Check(y)]=x; Parent[x]=z;
            Child[x][oo^1]=y; Parent[y]=x;
            PushUp(x); PushUp(y);
        }
        inline void Splay(int At,int To)
        {
            while(Parent[At]!=To)
            {
                int Father=Parent[At];
                if(Parent[Father]==To)
                {
                    Rotate(At);
                }
                else if(Check(At)==Check(Father))
                {
                    Rotate(Father); Rotate(At);
                }
                else
                {
                    Rotate(At); Rotate(At);
                }
            }
            if(To==0) Root=At;
        }
        inline void Insert(int Val)
        {
            int Now=Root,Par=0;
            while(Now)
            {
                Par=Now;
                Now=Child[Now][(Val>Quanzhi[Now])?1:0];
            }
            Now=++Points;
            if(Par)
            {
                Child[Par][(Val>Quanzhi[Par])?1:0]=Now;
            }
            Parent[Now]=Par;
            Child[Now][0]=Child[Now][1]=0;
            Quanzhi[Now]=Val;
            Size[Now]=1;
            Splay(Now,0);
        }
        inline int Ask_Kth(int Id)
        {
            int Now=Root;
            while(Now)
            {
                PushDown(Now);
                if(Size[Child[Now][0]]>=Id)
                {
                    Now=Child[Now][0];
                }
                else if(Size[Child[Now][0]]+1==Id)
                {
                    return Now;
                }
                else
                {
                    Id=Id-Size[Child[Now][0]]-1;
                    Now=Child[Now][1];
                }
            }
        }
        inline void Reverse(int l,int r)
        {
            int ll=Ask_Kth(l),rr=Ask_Kth(r+2);
            Splay(ll,0);
            Splay(rr,ll);
            int Pos=Child[rr][0];
            Rev[Pos]^=1;
        }
        inline void Output(int Now)
        {
            PushDown(Now);
            if(Child[Now][0]) Output(Child[Now][0]);
            if(Quanzhi[Now]>=1&&Quanzhi[Now]<=n) W(Quanzhi[Now]);
            if(Child[Now][1]) Output(Child[Now][1]);
        }
        inline void Solve()
        {
            Init();
            while(m--)
            {
                int l=read(),r=read();
                Reverse(l,r);
            }
            Output(Root);
        }
    }
    int main()
    {
        R(n); R(m);
        Pht::Solve();
        return 0;
    }
    /*
    input
    5 3
    1 3
    1 3
    1 4
    output
    4 3 2 1 5
    */
    View Code
  • 相关阅读:
    nginx-1.8.1的安装
    ElasticSearch 在3节点集群的启动
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
    LeetCode 501. Find Mode in Binary Search Tree (找到二叉搜索树的众数)
    LeetCode 437. Path Sum III (路径之和之三)
    LeetCode 404. Sum of Left Leaves (左子叶之和)
    LeetCode 257. Binary Tree Paths (二叉树路径)
    LeetCode Questions List (LeetCode 问题列表)- Java Solutions
    LeetCode 561. Array Partition I (数组分隔之一)
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10729887.html
Copyright © 2020-2023  润新知