3223. 文艺平衡树【平衡树-splay】

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是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

板子啊,常规操作

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #define MAXN (100000+10)
  5 using namespace std;
  6 int Father[MAXN];
  7 int Son[MAXN][2];
  8 int Size[MAXN];
  9 int Smark[MAXN];
 10 int a[MAXN];
 11 int Key[MAXN];
 12 int Root;
 13 int n,m,l,r;
 14 int Get(int x)
 15 {
 16     return Son[Father[x]][1]==x;
 17 }
 18 
 19 void Update(int x)
 20 {
 21     Size[x]=Size[Son[x][1]]+Size[Son[x][0]]+1;
 22 }
 23 
 24 void Pushdown(int x)
 25 {
 26     if (x && Smark[x])
 27     {
 28         Smark[Son[x][0]]^=1;
 29         Smark[Son[x][1]]^=1;
 30         swap(Son[x][0],Son[x][1]);
 31         Smark[x]=0;
 32     }
 33 }
 34 
 35 void Rotate(int x)
 36 {
 37     Pushdown(Father[x]);
 38     Pushdown(x);
 39     int fa=Father[x];
 40     int fafa=Father[fa];
 41     int wh=Get(x);
 42     
 43     Son[fa][wh]=Son[x][wh^1];
 44     Father[fa]=x;
 45     if (Son[fa][wh]) Father[Son[fa][wh]]=fa;
 46     
 47     Father[x]=fafa;
 48     Son[x][wh^1]=fa;
 49     if (fafa) Son[fafa][Son[fafa][1]==fa]=x;
 50     
 51     Update(fa);
 52     Update(x);
 53 }
 54 
 55 void Splay(int x,int tar)
 56 {
 57     for (int fa;(fa=Father[x])!=tar;Rotate(x))
 58         if (Father[fa]!=tar)
 59             Rotate(Get(fa)==Get(x)?fa:x);
 60     if (!tar) Root=x;
 61 }
 62 
 63 void Build (int l,int r,int fa)
 64 {
 65     if (l>r) return;
 66     int mid=(l+r)/2;
 67     if (mid<fa) Son[fa][0]=mid;
 68     if (mid>fa) Son[fa][1]=mid;
 69     Father[mid]=fa;
 70     Size[mid]=1;
 71     Key[mid]=a[mid];
 72     if (l==r) return;
 73     Build(l,mid-1,mid);
 74     Build(mid+1,r,mid);
 75     Update(mid);
 76 }
 77 
 78 int Findx(int x)
 79 {
 80     int now=Root;
 81     while (1)
 82     {
 83         Pushdown(now);
 84         if (x<=Size[Son[now][0]])
 85             now=Son[now][0];
 86         else
 87         {
 88             x-=Size[Son[now][0]];
 89             if (x==1) return now;
 90             x-=1;
 91             now=Son[now][1];
 92         }
 93     }
 94 }
 95 
 96 void Rever(int l,int r)
 97 {
 98     int f1=Findx(l);
 99     int f2=Findx(r+2);
100     Splay(f1,0);
101     Splay(f2,f1);
102     Smark[Son[Son[Root][1]][0]]^=1;
103 }
104 
105 void Write(int x)
106 {
107     Pushdown(x);
108     if (Son[x][0]) Write(Son[x][0]);
109     if (x>=2 && x<=n+1) printf("%d ",Key[x]);
110     if (Son[x][1]) Write(Son[x][1]);
111 }
112 
113 int main()
114 {
115     scanf("%d%d",&n,&m);
116     for (int i=2;i<=n+1;++i)
117         a[i]=i-1;
118     Build(1,n+2,0);Root=(n+3)/2;
119     for (int i=1;i<=m;++i)
120     {
121         scanf("%d%d",&l,&r);
122         if (l>=r) continue;
123         Rever(l,r);
124     }
125     Write(Root);
126 }
原文地址:https://www.cnblogs.com/refun/p/8678699.html