zoukankan      html  css  js  c++  java
  • BZOJ2329 [HNOI2011]括号修复

    把左括号看做$1$,右括号看做$-1$,于是查询操作等于查询一个区间左边右边最大(最小)子段和

    支持区间翻转,反转,覆盖操作。。。注意如果有覆盖操作,之前的操作全部作废了。。。于是在下传标记的时候要最后做。。。

      1 /**************************************************************
      2     Problem: 2329
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:4252 ms
      7     Memory:7352 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 #define _max(x, y) (x > y ? x : y)
     14 #define _min(x, y) (x < y ? x : y)
     15 using namespace std;
     16 const int N = 1e5 + 5;
     17  
     18 int read();
     19 int get_c();
     20 int get_op();
     21  
     22 namespace treap {
     23     struct node;
     24     node *root, *null;
     25      
     26     struct node {
     27         node *ls, *rs;
     28         int val, rev, inv, fill, maxl, maxr, minl, minr, sum, sz;
     29          
     30         #define Len (1 << 16)
     31         inline void* operator new(size_t, int _v = 0) { 
     32             static node *mempool, *c;
     33             if (mempool == c)
     34                 mempool = (c = new node[Len]) + Len;
     35             c -> ls = c -> rs = null;
     36             c -> val = c -> sum = _v, c -> rev = c -> inv = c -> fill = 0;
     37             c -> maxl = c -> maxr =  c -> minl = c -> minr = 0;
     38             c -> sz = 1;
     39             return c++;
     40         }
     41         #undef Len
     42                  
     43         inline void reverse() {
     44             rev ^= 1;
     45             swap(ls, rs);
     46             swap(minl, minr), swap(maxl, maxr);
     47         }
     48         inline void inverse() {
     49             inv ^= 1;
     50             fill = -fill, val = -val, sum = -sum;
     51             swap(maxl, minl), maxl = -maxl, minl = -minl;
     52             swap(maxr, minr), maxr = -maxr, minr = -minr;
     53         }
     54         inline void replace(int t) {
     55             fill = val = t, sum = sz * t;
     56             maxl = maxr = sz * (t == 1);
     57             minl = minr = -sz * (t == -1);
     58         }
     59  
     60         inline node* update() {
     61             sz = ls -> sz + rs -> sz + 1;
     62             sum = ls -> sum + rs -> sum + val;
     63             maxl = _max(ls -> maxl, ls -> sum + val + _max(0, rs -> maxl));
     64             minl = _min(ls -> minl, ls -> sum + val + _min(0, rs -> minl));
     65             maxr = _max(rs -> maxr, rs -> sum + val + _max(0, ls -> maxr));
     66             minr = _min(rs -> minr, rs -> sum + val + _min(0, ls -> minr));
     67             return this;
     68         }
     69         inline node* push() {
     70             if (rev) {
     71                 ls -> reverse(), rs -> reverse();
     72                 rev = 0;
     73             }
     74             if (inv) {
     75                 ls -> inverse(), rs -> inverse();
     76                 inv = 0; 
     77             }
     78             if (fill) {
     79                 ls -> replace(fill), rs -> replace(fill);
     80                 fill = 0;
     81             }
     82             return this;
     83         }
     84     };
     85      
     86     inline void init() {
     87         null = new()node;
     88         null -> ls = null -> rs = null;   
     89         null -> sz = null -> val = 0;
     90     }
     91      
     92     inline unsigned int Rand() {
     93         static unsigned int res = 2333;
     94         return res += res << 2 | 1;
     95     }
     96     inline int random(int x, int y) {
     97         return Rand() % (x + y) < x;
     98     }
     99      
    100     void build(node *&p, int l, int r, int *a) {
    101         if (l > r) {
    102             p = null;
    103             return;
    104         }
    105         p = new(a[l + r >> 1])node;
    106         if (l == r) {
    107             p -> update();
    108             return;
    109         }
    110         build(p -> ls, l, (l + r >> 1) - 1, a);
    111         build(p -> rs, (l + r >> 1) + 1, r, a);
    112         p -> update();
    113     }
    114      
    115     void merge(node *&p, node *x, node *y) {
    116         if (x == null || y == null)
    117             p = x == null ? y -> push() : x -> push();
    118         else if (random(x -> sz, y -> sz)) {
    119             p = x -> push();
    120             merge(p -> rs, x -> rs, y);
    121         } else {
    122             p = y -> push();
    123             merge(p -> ls, x, y -> ls);
    124         }
    125         p -> update();
    126     }
    127      
    128     void split(node *p, node *&x, node *&y, int k) {
    129         if (!k) {
    130             x = null, y = p -> push();
    131             return;
    132         }
    133         if (k == p -> sz) {
    134             x = p -> push(), y = null;
    135             return;
    136         }
    137         if (p -> ls -> sz >= k) {
    138             y = p -> push();
    139             split(p -> ls, x, y -> ls, k);
    140             y -> update();
    141         } else {
    142             x = p -> push();
    143             split(p -> rs, x -> rs, y, k - p -> ls -> sz - 1);
    144             x -> update();
    145         }
    146     }
    147 }
    148 using namespace treap;
    149  
    150 int n;
    151 int a[N];
    152  
    153 int main() {
    154     int Q, i, oper, l, r;
    155     node *x, *y, *z;
    156     init();
    157     n = read(), Q = read();
    158     for (i = 1; i <= n; ++i) a[i] = get_c();
    159     build(root, 1, n, a);
    160     while (Q--) {
    161         oper = get_op(), l = read(), r = read();
    162         split(root, x, y, l - 1), split(y, y, z, r - l + 1);
    163         if (oper == 0) y -> replace(get_c());
    164         else if (oper == 1) printf("%d
    ", (y -> maxr + 1) / 2 - (y -> minl - 1) / 2);
    165         else if (oper == 2) y -> reverse();
    166         else if (oper == 3) y -> inverse();
    167         merge(root, x, y -> push()), merge(root, root, z);
    168     }
    169     return 0;
    170 }
    171  
    172 inline int read() {
    173     register int x = 0;
    174     register char ch = getchar();
    175     while (ch < '0' || '9' < ch) ch = getchar();
    176     while ('0' <= ch && ch <= '9')
    177         x = x * 10 + ch - '0', ch = getchar();
    178     return x;
    179 }
    180  
    181 inline int get_c() {
    182     register char ch = getchar();
    183     while (ch != '(' && ch != ')') ch = getchar();
    184     return ch == '(' ? 1 : -1;
    185 }
    186  
    187 inline int get_op() {
    188     register char ch = getchar();
    189     while (ch != 'R' && ch != 'Q' && ch != 'S' && ch != 'I') ch = getchar();
    190     if (ch == 'R') return 0;
    191     if (ch == 'Q') return 1;
    192     if (ch == 'S') return 2;
    193     if (ch == 'I') return 3;
    194 }
    View Code
  • 相关阅读:
    useState 的介绍和多状态声明(二)
    PHP:相对于C#,PHP中的个性化语法
    PHP:IIS下的PHP开发环境搭建
    PHP:同一件事,有太多的方式
    Javascript:再论Javascript的单线程机制 之 DOM渲染时机
    Javascript:拦截所有AJAX调用,重点处理服务器异常
    DDD:谈谈数据模型、领域模型、视图模型和命令模型
    .NET:再论异常处理,一个真实的故事
    Javascript:由 “鸭子类型” 得出来的推论
    Workflow:采用坐标变换(移动和旋转)画箭头
  • 原文地址:https://www.cnblogs.com/rausen/p/4532055.html
Copyright © 2011-2022 走看看