zoukankan      html  css  js  c++  java
  • [代码] bzoj 1500 维修数列(无旋treap)

    - 传送门 -

     http://www.lydsy.com/JudgeOnline/problem.php?id=1500
     

    1500: [NOI2005]维修数列

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 15301  Solved: 5063

    Description

    Input

    输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
    第2行包含N个数字,描述初始时的数列。
    以下M行,每行一条命令,格式参见问题描述中的表格。
    任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
    插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

    Output

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    Sample Input

    9 8
    2 -6 3 5 1 -5 -3 6 3
    GET-SUM 5 4
    MAX-SUM
    INSERT 8 3 -5 7 2
    DELETE 12 1
    MAKE-SAME 3 3 2
    REVERSE 3 6
    GET-SUM 5 4
    MAX-SUM

    Sample Output

    -1
    10
    1
    10

    HINT

    - 代码 -

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <ctime>
    #include <cstdlib>
    #define pii pair<int, int>
    #define mp make_pair
    #define ls C[rt][0]
    #define rs C[rt][1]
    using namespace std;
    
    template <typename ty> void read(ty &x) {
      x = 0; int f = 1; char ch = getchar();
      while (ch > '9' || ch < '0') { if (ch == '-') f = -1; ch = getchar(); }
      while (ch >= '0' && ch <= '9') { x = x*10 + ch - '0'; ch = getchar(); }
      x *= f;
    }
    template <typename ty> ty Max(ty a, ty b) { return a > b ? a : b; }
    template <typename ty> ty Min(ty a, ty b) { return a < b ? a : b; }
    template <typename ty> int Chkmin(ty a, ty b) { return a > b ? a = b, 1 : 0; }
    template <typename ty> int Chkmax(ty a, ty b) { return a < b ? a = b, 1 : 0; }
    
    typedef long long LL;
    typedef double db;
    
    const int inf = 0x7fffffff;
    const int N = 5e5 + 160;
    
    int V[N], C[N][2], S[N], STK[N], KEY[N];
    int TAG[N], REV[N], A[N], Q[4000016];
    int LM[N], RM[N], TM[N], T[N];
    int root, n, m, sz, tot;
    int pos, t, c;
    
    char OP[160];
    
    void pushtag(int rt, int val) {
    
      if (!rt) return;
      V[rt] = val;
      T[rt] = S[rt] * val;
      LM[rt] = RM[rt] = TM[rt] = Max(val, val * S[rt]);
      TAG[rt] = 1;
    
    }
    
    void pushrev(int rt) {
    
      if (!rt) return;
      swap(C[rt][0], C[rt][1]);
      swap(LM[rt], RM[rt]);
      REV[rt] ^= 1;
    
    }
    
    void pushup(int rt) {
    
      if (!rt) return;
      S[rt] = S[ls] + S[rs] + 1;
      T[rt] = T[ls] + T[rs] + V[rt];
      LM[rt] = Max(LM[ls], T[ls] + V[rt] + Max(LM[rs], 0));
      RM[rt] = Max(RM[rs], T[rs] + V[rt] + Max(RM[ls], 0));
      TM[rt] = Max(TM[ls], Max(TM[rs], V[rt] + Max(LM[rs], 0) + Max(RM[ls], 0)));
    
    }
    
    void pushdown(int rt) {
    
      if (!rt) return;
     
      if (TAG[rt]) {
        
        pushtag(ls, V[rt]);
        pushtag(rs, V[rt]);
        TAG[rt] = REV[rt] = 0;
    
      }
    
      if (REV[rt]) {
        
        pushrev(ls);
        pushrev(rs);
        REV[rt] = 0;
    
      }
    
    }
    
    int new_node() {
    
      int a, b;
      read(a);
      if (tot) b = Q[tot--];
      else b = ++sz;
      V[b] = a; KEY[b] = rand();
      C[b][0] = C[b][1] = 0;
      S[b] = 1; TAG[b] = REV[b] = 0;
      LM[b] = RM[b] = TM[b] = T[b] = a;
      return b;
    
    }
    
    int build(int s) {
    
      int lst = 0, top = 0;
      for (int i = 1; i <= s; ++ i) {
        
        int tmp = new_node(); lst = 0;
        while (top && KEY[tmp] < KEY[STK[top]]) {
          pushup(STK[top]);
          lst = STK[top];
          STK[top--] = 0;
        }
        if (lst) C[tmp][0] = lst;
        if (top) C[STK[top]][1] = tmp;
        STK[++top] = tmp;
    
      }
    
      while (top) pushup(STK[top--]);
      return STK[1];
    
    }
    
    pii split(int rt, int k) {
    
      if (!rt) return mp(0, 0);
      
      pii tmp;
      pushdown(rt);
      
      if (k > S[C[rt][0]]) {
        tmp = split(C[rt][1], k - S[C[rt][0]] - 1);
        C[rt][1] = tmp.first; pushup(rt); tmp.first = rt;
      }
      else {
        tmp = split(C[rt][0], k);
        C[rt][0] = tmp.second; pushup(rt); tmp.second = rt;
      }
      
      return tmp;
    
    }
    
    int merge(int ra, int rb) {
    
      if (!ra) return rb;
      if (!rb) return ra;
      
      pushdown(ra);
      pushdown(rb);
    
      if (KEY[ra] < KEY[rb]) {
        C[ra][1] = merge(C[ra][1], rb);
        pushup(ra); return ra;
      }
      else {
        C[rb][0] = merge(ra, C[rb][0]);
        pushup(rb); return rb;
      }
    
    }
    
    void recycle(int rt) {
    
      if (!rt) return;
      Q[++tot] = rt;
      recycle(C[rt][0]);
      recycle(C[rt][1]);
    
    }
    
    void work1() {
    
      read(pos); read(t);
      pii a = split(root, pos);
      root = merge(a.first, merge(build(t), a.second));
    
    }
    
    void work2() {
    
      read(pos); read(t);
      pii a = split(root, pos - 1);
      pii b = split(a.second, t);
      recycle(b.first);
      root = merge(a.first, b.second);
    
    }
    
    void work3() {
    
      read(pos); read(t); read(c);
      if (!t) return;
      pii a = split(root, pos - 1);
      pii b = split(a.second, t);
      pushtag(b.first, c);
      root = merge(a.first, merge(b.first, b.second));
    
    }
    
    void work4() {
    
      read(pos); read(t);
      if (!t) return;
      pii a = split(root, pos - 1);
      pii b = split(a.second, t);
      pushrev(b.first);
      root = merge(a.first, merge(b.first, b.second));
    
    }
    
    void work5() {
    
      read(pos); read(t);
      if (!t) { printf("0
    "); return; }
      pii a = split(root, pos - 1);
      pii b = split(a.second, t);
      printf("%d
    ", T[b.first]);
      root = merge(a.first, merge(b.first, b.second));
    
    }
    
    void work6() { printf("%d
    ", TM[root]); }
    
    int main () {
    
      read(n); read(m);
    
      LM[0] = RM[0] = TM[0] = V[0] = -inf;
      root = build(n);
      for (int i = 1; i <= m; ++ i) {
        scanf("%s", OP);
        if (OP[0] == 'I') work1();
        if (OP[0] == 'D') work2();
        if (OP[2] == 'K') work3();
        if (OP[0] == 'R') work4();
        if (OP[0] == 'G') work5();
        if (OP[2] == 'X') work6(); 
      }
    
      return 0;
    
    }
    
  • 相关阅读:
    Pytorch 随机数种子设置
    python 利用 dictionary 的 .get() 操作,避免写 if-else
    PEP-8 or google 风格 python 代码风格和注释规范
    Vim 多文件切换使用
    Shell 变量及脚本使用
    python numpy 大矩阵运算容易内存爆炸
    Ubuntu 配置 Pytorch on Graph (PoG) 环境
    Markdown 学习笔记
    Linux-saltstack
    Python字符串详解
  • 原文地址:https://www.cnblogs.com/Anding-16/p/8010712.html
Copyright © 2011-2022 走看看