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

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

题目背景

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

题目描述

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

输入输出格式

输入格式:

 

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, \cdots n-1,n)(1,2,n1,n) m表示翻转操作次数

接下来m行每行两个数 [l,r][l,r] 数据保证 1 \leq l \leq r \leq n1lrn

 

输出格式:

 

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

 

输入输出样例

输入样例#1:
5 3
1 3
1 3
1 4
输出样例#1:
4 3 2 1 5

说明

n, m \leq 100000n,m100000

code

  1 #include<cstdio>
  2 #include<algorithm>
  3 
  4 using namespace std;
  5 
  6 const int MAXN = 100100;
  7 int fa[MAXN],ch[MAXN][2],tag[MAXN],siz[MAXN],id[MAXN];
  8 int n,m,root,sz;
  9 
 10 int read()
 11 {
 12     int x = 0;char ch = getchar();
 13     while (ch<'0'||ch>'9') ch = getchar();
 14     while (ch>='0'&&ch<='9') x = x*10+ch-'0',ch = getchar();
 15     return x;
 16 }
 17 void pushup(int x)
 18 {
 19     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
 20 }
 21 void pushdown(int x)
 22 {
 23     if (tag[x])
 24     {
 25         tag[ch[x][0]] ^= 1;
 26         tag[ch[x][1]] ^= 1;
 27         swap(ch[x][0],ch[x][1]);
 28         tag[x] = 0;
 29     }
 30 }
 31 int son(int x)
 32 {
 33     return ch[fa[x]][1]==x;
 34 }
 35 void rotate(int x)
 36 {
 37     int y = fa[x],z = fa[y],b = son(x),c = son(y),a = ch[x][!b];
 38     if (z) ch[z][c] = x;else root = x;fa[x] = z;
 39     if (a) fa[a] = y;ch[y][b] = a;
 40     ch[x][!b] = y;fa[y] = x;
 41     pushup(y);
 42 }
 43 void splay(int &x,int rt)
 44 {
 45     while (fa[x]!=rt)
 46     {
 47         int y = fa[x],z = fa[y];
 48         if (z==rt) rotate(x);
 49         else
 50         {
 51             if (son(x)==son(y)) rotate(y),rotate(x);
 52             else rotate(x), rotate(x);
 53         }
 54     }
 55     pushup(x);
 56 }
 57 int getkth(int rt,int k)
 58 {
 59     pushdown(rt);
 60     int l = ch[rt][0],r = ch[rt][1];
 61     if (k==siz[l]+1) return rt;
 62     else if (k<siz[l]+1) return getkth(l,k);
 63     else return getkth(r,k-siz[l]-1);
 64 }
 65 void reverse(int l,int r)
 66 {
 67     int tl = getkth(root,l),tr = getkth(root,r+2);
 68     splay(tl,0);splay(tr,tl);
 69     tag[ch[tr][0]] ^= 1;
 70 }
 71 void build(int l,int r,int f)
 72 {
 73     if (l>r) return ;
 74     int now = id[l],last = id[f];
 75     if (l==r) 
 76     {
 77         fa[now] = last;
 78         siz[now] = 1;
 79         if (l<f) ch[last][0] = now;
 80         else ch[last][1] = now;
 81         return ;
 82     }
 83     int mid = (l+r)>>1;
 84     now = id[mid];
 85     build(l,mid-1,mid);
 86     build(mid+1,r,mid);
 87     fa[now] = last;
 88     pushup(mid);
 89     if (mid<f) ch[last][0] = now;
 90     else ch[last][1] = now;
 91 }
 92 int main()
 93 {
 94     n = read();m = read();
 95     for (int i=1; i<=n+2; ++i) id[i] = ++sz;
 96     build(1,n+2,0);root = (n+3)>>1;        
 97     while (m--)
 98     {
 99         int x = read(),y = read();
100         reverse(x,y);
101     }
102     for (int i=2; i<=n+1; ++i)
103         printf("%d ",getkth(root,i)-1);
104     return 0;
105 }

 

 

posted @ 2017-08-13 08:07  MJT12044  阅读(222)  评论(0编辑  收藏  举报