• 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
  • 相关阅读:
    firefox 插件开发2
    android ndk
    android Fragment.
    排序算法
    php中判断iphone版本
    php css
    ndk 入门实例
    howtoaddabuttontopreferencescreen 自定义view
    分布式K/V存储方案
    android版 eclipse
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8375745.html
Copyright © 2020-2023  润新知