SplayP3391【模板】文艺平衡树

原题链接:https://www.luogu.com.cn/problem/P3391

题意:

您需要写一种数据结构(可参考题目标题),来维护一个有序数列。

其中需要提供以下操作:翻转一个区间,例如原有序序列是 5 4 3 2 1,翻转区间是 [2,4]的话,结果是 5 2 3 4 1

思路:

文艺平衡树的模板题;以下标建一棵树,每次按照规则旋转就好

代码:

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
const int maxn=0x7fffff;
inline char nc()
{
    static char buf[MAXN],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
int n,m;
struct node
{
    int tot,fa,ch[2];
    bool rev;
}T[MAXN];
int tot,point;
int root;
int PosL,PosR;
inline void connect(int x,int fa,bool how)
{
    T[x].fa=fa;
    T[fa].ch[how]=x;
}
inline void update(int k)
{
    T[k].tot=T[T[k].ch[0]].tot+T[T[k].ch[1]].tot+1;
}
inline int BuildTree(int l,int r)
{
    if(l>r) return 0;
    int mid=(l+r)>>1;
    connect(BuildTree(l,mid-1),mid,0);
    connect(BuildTree(mid+1,r),mid,1);
    T[mid].rev=0;
    update(mid);
    return mid;
}
inline bool ident(int x)
{
    return T[T[x].fa].ch[1]==x;
}
inline void pushdown(int x)
{
    if(T[x].rev)
    {
        swap(T[x].ch[0],T[x].ch[1]);
        T[T[x].ch[0]].rev^=1;
        T[T[x].ch[1]].rev^=1;    
        T[x].rev=0;
    }
}
inline void rotate(int X)
{
   // pushdown(T[X].fa);pushdown(X);
    int Y=T[X].fa;
    if(Y==root)    root=X;
    int R=T[Y].fa;
    bool Yson=ident(X);
    bool Rson=ident(Y);
    int B=T[X].ch[Yson^1];
    connect(B,Y,Yson);
    connect(Y,X,Yson^1);
    connect(X,R,Rson);
    update(Y);update(X);
}
inline void splay(int x,int to)
{
    while(T[x].fa!=to)
    {
        if(T[T[x].fa].fa==to)        rotate(x);
        else if(ident(x)==ident(T[x].fa)) rotate(T[x].fa),rotate(x);
        else rotate(x),rotate(x);
    }
    update(x);
}
inline int find(int x)
{
    int now=root;x--;
    pushdown(now);
    while(x!=T[T[now].ch[0]].tot)
    {
        if (T[T[now].ch[0]].tot<x) x-=T[T[now].ch[0]].tot+1,now=T[now].ch[1];
          else now=T[now].ch[0];
        pushdown(now);
    }
    return now;
}
void print(int now)
{
    if(!now)    return ;
    pushdown(now);
    print(T[now].ch[0]);
    if(now!=1&&now!=n+2) printf("%d ",now-1);
    print(T[now].ch[1]);
}
int main()
{ 
    cin>>n>>m;
    root=BuildTree(1,n+2);
    for(int i=1;i<=m;i++)
    {
        int l,r;
        cin>>l>>r;
        PosL=find(l);
        splay(PosL,0);
        PosR=find(r+2);
        splay(PosR,root);
        T[T[PosR].ch[0]].rev^=1;
    }
    print(root);
}

 

posted @ 2020-12-07 20:46  Shmilky  阅读(102)  评论(0编辑  收藏  举报