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

  • 相关阅读:
    sql server还原数据库(请选择用于还原的备份集)
    初学K3Cloud开发
    SQL-视图
    2019-07-31 C#基础知识学习
    2019-07-30 C#基础知识学习
    初学数据库
    什么时候该使用SUM()函数
    Mongo Document 校验
    Linux Mysql操作命令
    说一说Unsafe魔法类
  • 原文地址:https://www.cnblogs.com/yousiki/p/6148268.html
Copyright © 2011-2022 走看看