BZOJ3223: Tyvj 1729 文艺平衡树

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 5918  Solved: 3535
[Submit][Status][Discuss]

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

Source

 

【题解】

平衡树维护序列,大小顺序与节点内的权值无关,而是通过一开始钦定树的形态来钦定大小顺序

反转操作,把区间放到一颗子树内,显然子树根节点在区间中点,直接交换子树即可

  1 /**************************************************************
  2     Problem: 3223
  3     User: 33511595
  4     Language: C++
  5     Result: Accepted
  6     Time:3040 ms
  7     Memory:13012 kb
  8 ****************************************************************/
  9  
 10 #include <iostream>
 11 #include <cstdio>
 12 #include <cstring>
 13 #include <cstdlib>
 14 #include <algorithm>
 15 #include <queue>
 16 #include <vector>
 17 #include <map>
 18 #include <string> 
 19 #include <cmath> 
 20 #define min(a, b) ((a) < (b) ? (a) : (b))
 21 #define max(a, b) ((a) > (b) ? (a) : (b))
 22 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
 23 template <class T>
 24 inline void swap(T& a, T& b)
 25 {
 26     T tmp = a;a = b;b = tmp;
 27 }
 28 inline void read(int &x)
 29 {
 30     x = 0;char ch = getchar(), c = ch;
 31     while(ch < '0' || ch > '9') c = ch, ch = getchar();
 32     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
 33     if(c == '-') x = -x;
 34 }
 35  
 36 const int INF = 0x3f3f3f3f;
 37 const int MAXN = 500000 + 10;
 38  
 39 int ch[MAXN][2], fa[MAXN], size[MAXN], root,tag[MAXN], data[MAXN];
 40 int son(int x){return x == ch[fa[x]][1];}
 41 void pushup(int rt)
 42 {
 43     size[rt] = size[ch[rt][1]] + size[ch[rt][0]] + 1;
 44 }
 45 void pushdown(int rt)
 46 {
 47     if(!tag[rt]) return; 
 48     int l = ch[rt][0], r = ch[rt][1];
 49     tag[l] ^= 1, tag[r] ^= 1;
 50     swap(ch[l][0], ch[l][1]);
 51     swap(ch[r][0], ch[r][1]);
 52     tag[rt] = 0;
 53 }
 54 void rotate(int x)
 55 {
 56     int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
 57     if(z) ch[z][c] = x; else root = x; fa[x] = z;
 58     if(a) fa[a] = y; ch[y][b] = a;
 59     ch[x][!b] = y, fa[y] = x;
 60     pushup(y), pushup(x);
 61 }
 62 void splay(int x, int i)
 63 {
 64     while(fa[x] != i)
 65     {
 66         int y = fa[x], z = fa[y];
 67         if(z == i) rotate(x);
 68         else
 69             if(son(x) == son(y)) rotate(y), rotate(x);
 70             else rotate(x), rotate(x);
 71     }
 72 }
 73 int getkth(int rt, int x)
 74 {
 75     pushdown(rt);int l = ch[rt][0];
 76     if(size[l] + 1 == x) return rt;
 77     else if(size[l] + 1 > x) return getkth(ch[rt][0], x);
 78     else return getkth(ch[rt][1], x - size[l] - 1);
 79 }
 80 void turn(int l, int r)
 81 {
 82     l = getkth(root, l - 1), r = getkth(root, r + 1);
 83     splay(l, 0);splay(r, l);
 84     int now = ch[r][0];
 85     tag[now] ^= 1;
 86     swap(ch[now][0], ch[now][1]);
 87     pushdown(now);
 88 }
 89 int n, m, tmp1, tmp2;
 90 void put(int x)
 91 {
 92     if(!x) return;
 93     pushdown(x);
 94     put(ch[x][0]);
 95     if(x != 1 && x != n + 2)printf("%d ", data[x]);
 96     put(ch[x][1]);
 97     return;
 98 }
 99 int main()
100 {
101     read(n), read(m);
102     root = 1;
103     for(int i = 1;i <= n + 1;++ i) ch[i][1] = i + 1, fa[i + 1] = i, size[i] = n + 3 - i;
104     size[n + 2] = 1;
105     for(int i = 2;i <= n + 1;++ i) data[i] = i - 1;
106     for(int i = 1;i <= m;++ i)
107     {
108         read(tmp1), read(tmp2);
109         turn(tmp1 + 1, tmp2 + 1);
110     }
111     put(root);
112     return 0;
113 }
BZOJ3223

 

posted @ 2018-01-29 08:22  嘒彼小星  阅读(106)  评论(0编辑  收藏  举报