• 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
  • 相关阅读:
    常见数据结构图文详解-C++版
    求单链表中环的起点,原理详解
    Qt Creator 整合 python 解释器教程
    Qt 共享库(动态链接库)和静态链接库的创建及调用
    qt creator 中的"提升为..."功能简介
    QT 操作 excel 教程
    网易2017校园招聘算法题c语言实现源码
    c语言版贪吃蛇小游戏
    mysql语法结构
    Spring MVC rest接收json中文格式数据显示乱码
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10729887.html
Copyright © 2020-2023  润新知