zoukankan      html  css  js  c++  java
  • BZOJ 3223: Tyvj 1729 文艺平衡树

    3223: Tyvj 1729 文艺平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 3628  Solved: 2052
    [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

    [Submit][Status][Discuss]

    小生的第三道伸展树板子题。初识Splay维护区间翻转操作。引用一位前辈的题解。、

    splay的经典操作:翻转区间-->交换左右子树,注意打标记降低翻转次数。如何找到要操作的区间[l,r]:将当前排名(size)为l-1 +1 的节点转到根,将当前排名为r+2的节点转到根的右子树的根节点,则根的右子树的根节点的左子树为所求区间,直接打标记就可以了。

      1 #include <bits/stdc++.h>
      2 
      3 class Splay {
      4 public:
      5     Splay(void) {
      6         root = NULL;
      7         for (top = 0; top < siz; ++top)
      8             stk[top] = tree + top;
      9     }
     10     
     11     inline void auto_build(int n) {
     12         for (int i = 0; i <= n + 1; ++i)
     13             insert(i);
     14     }
     15     
     16     inline void insert(int val) {
     17         if (root == NULL)
     18             root = newnode(val, NULL);
     19         else {
     20             node *t = root;
     21             while (t->son[1] != NULL)
     22                 t = t->son[1];
     23             splay(t, NULL);
     24             t->son[1] = newnode(val, t);
     25             update(root); splay(t->son[1], NULL);
     26         }
     27     }
     28     
     29     inline void reverse(int l, int r) {
     30         ++l, ++r;
     31         splay(rnk(l - 1), NULL);
     32         splay(rnk(r + 1), root);
     33         reverse(root->son[1]->son[0]);
     34     }
     35     
     36     inline void print(int n) {
     37         for (int i = 1; i <= n; ++i)
     38             printf("%d ", rnk(i + 1)->value);
     39     }
     40 private:
     41     const static int siz = 1e5 + 5;
     42     
     43     struct node {
     44         int size;
     45         int value;
     46         bool reverse;
     47         node *father;
     48         node *son[2];
     49     }*root;
     50     
     51     node tree[siz], *stk[siz]; int top;
     52     
     53     inline node *newnode(int v, node *f) {
     54         node *ret = stk[--top];
     55         ret->size = 1;
     56         ret->value = v;
     57         ret->father = f;
     58         ret->son[0] = NULL;
     59         ret->son[1] = NULL;
     60         ret->reverse = false;
     61         return ret;
     62     }
     63     
     64     inline void freenode(node *t) {
     65         stk[top++] = t;
     66     }
     67     
     68     inline int size(node *t) {
     69         return t == NULL ? 0 : t->size;
     70     }
     71     
     72     inline void update(node *t) {
     73         t->size = 1;
     74         t->size += size(t->son[0]);
     75         t->size += size(t->son[1]);
     76     }
     77     
     78     inline bool son(node *f, node *s) {
     79         if (f == NULL)return false;
     80         return f->son[1] == s;
     81     }
     82     
     83     inline bool tag(node *t) {
     84         return t == NULL ? false : t->reverse;
     85     }
     86     
     87     inline void reverse(node *t) {
     88         if (t != NULL)
     89             t->reverse ^= true;
     90     }
     91     
     92     inline void pushdown(node *t) {
     93         if (tag(t)) {
     94             std::swap(t->son[0], t->son[1]);
     95             reverse(t->son[0]);
     96             reverse(t->son[1]);
     97             t->reverse ^= true;
     98         }
     99     }
    100     
    101     inline void connect(node *f, node *s, bool k) {
    102         if (f == NULL)
    103             root = s;
    104         else
    105             f->son[k] = s;
    106         if (s != NULL)
    107             s->father = f;
    108     }
    109     
    110     inline void rotate(node *t) {
    111         node *f = t->father;
    112         node *g = f->father;
    113         bool a = son(f, t), b = !a;
    114         connect(f, t->son[b], a);
    115         connect(g, t, son(g, f));
    116         connect(t, f, b);
    117         update(f);
    118         update(t);
    119     }
    120     
    121     inline void splay(node *t, node *p) {if (t)
    122         while (t->father != p) {
    123             node *f = t->father;
    124             node *g = f->father;
    125             pushdown(g);
    126             pushdown(f);
    127             pushdown(t);
    128             if (g == p)
    129                 rotate(t);
    130             else {
    131                 if (son(g, f) ^ son(f, t))
    132                     rotate(t), rotate(t);
    133                 else
    134                     rotate(f), rotate(t);
    135             }
    136         }
    137     }
    138     
    139     inline node *find(int val) {
    140         node *ret = root;
    141         while (ret != NULL && ret->value != val)
    142             pushdown(ret), ret = ret->son[val >= ret->value];
    143         return ret;
    144     }
    145     
    146     inline node *rnk(int kth) {
    147         for (node *t = root; t; ) {
    148             pushdown(t);
    149             if (size(t->son[0]) < kth) {
    150                 kth -= size(t->son[0]);
    151                 if (kth == 1)
    152                     return t;
    153                 else
    154                     --kth, t = t->son[1];
    155             }
    156             else
    157                 t = t->son[0];
    158         }
    159     }
    160 }S;
    161 
    162 signed main(void) {
    163     int n, m; scanf("%d%d", &n, &m);
    164     S.auto_build(n);
    165     for (int i = 1, l, r; i <= m; ++i)
    166         scanf("%d%d", &l, &r), S.reverse(l, r);
    167     S.print(n);
    168 }

    @Author: YouSiki

  • 相关阅读:
    Python学习札记(十五) 高级特性1 切片
    LeetCode Longest Substring Without Repeating Characters
    Python学习札记(十四) Function4 递归函数 & Hanoi Tower
    single number和变体
    tusen 刷题
    实验室网站
    leetcode 76. Minimum Window Substring
    leetcode 4. Median of Two Sorted Arrays
    leetcode 200. Number of Islands 、694 Number of Distinct Islands 、695. Max Area of Island 、130. Surrounded Regions 、434. Number of Islands II(lintcode) 并查集 、178. Graph Valid Tree(lintcode)
    刷题注意事项
  • 原文地址:https://www.cnblogs.com/yousiki/p/6148268.html
Copyright © 2011-2022 走看看