zoukankan      html  css  js  c++  java
  • [NOI2005]维护数列

    [LuoguP2042]

    肝了一晚上和一上午,先把代码发了,等有时间(假期?)把较为详细的解释补一下(

    Code:

      1 #include <bits/stdc++.h>
      2 #define ll long long
      3 #define L(x) e[x].son[0]
      4 #define R(x) e[x].son[1]
      5 #define lx(x) e[x].left
      6 #define rx(x) e[x].right
      7 #define mx(x) e[x].mx
      8 #define sum(x) e[x].sum
      9 using namespace std;
     10 const int N = 1e6 + 7;
     11 const int inf = 0x3f3f3f3f;
     12 ll read() {
     13     ll re = 0, f = 1;
     14     char ch = getchar();
     15     while (ch < '0' || ch > '9') {if (ch == '-') f = -f; ch = getchar();}
     16     while ('0' <= ch && ch <= '9') {re = re * 10 + ch - '0'; ch = getchar();}
     17     return re * f;
     18 }
     19 int n, m, root, cnt;
     20 struct node{
     21     int val, father;
     22     int son[2];
     23     int siz;
     24     int sum, mx;
     25     int left, right;
     26     bool tag, rev;
     27 }e[N];
     28 int top, a[N], id[N], rub[N];
     29 void update(int x) {
     30     int l = L(x), r = R(x);
     31     sum(x) = sum(l) + sum(r) + e[x].val;
     32     e[x].siz = e[l].siz + e[r].siz + 1;
     33     mx(x) = max(mx(l), max(mx(r), rx(l) + e[x].val + lx(r)));
     34     lx(x) = max(lx(l), sum(l) + e[x].val + lx(r));
     35     rx(x) = max(rx(r), sum(r) + e[x].val + rx(l));
     36 }
     37 void pushdown(int x) {
     38     int l = L(x), r = R(x);
     39     if (e[x].tag) {
     40         e[x].tag = e[x].rev = false;
     41         if (l) {
     42             e[l].tag = true, e[l].val = e[x].val, sum(l) = e[x].val * e[l].siz;
     43             lx(l) = rx(l) = max(sum(l), 0);
     44             mx(l) = max(sum(l), e[l].val);
     45         }
     46         if (r) {
     47             e[r].tag = true, e[r].val = e[x].val, sum(r) = e[x].val * e[r].siz;
     48             lx(r) = rx(r) = max(sum(r), 0);
     49             mx(r) = max(sum(r), e[r].val);
     50         }
     51     }
     52     if (e[x].rev) {
     53         e[x].rev = false;
     54         e[l].rev ^= 1, e[r].rev ^= 1;
     55         swap(lx(l), rx(l)), swap(lx(r), rx(r));
     56         swap(L(l), R(l)), swap(L(r), R(r));
     57     }
     58 }
     59 void connect(int x, int fa, int Son) {
     60     e[x].father = fa;
     61     e[fa].son[Son] = x;
     62 }
     63 int identify(int x) {
     64     return L(e[x].father) == x ? 0 : 1;
     65 }
     66 void rotate(int x) {
     67     int fa = e[x].father, fason = identify(x);
     68     int gfa = e[fa].father, gfason = identify(fa);
     69     int B = e[x].son[fason ^ 1];
     70     connect(B, fa, fason), connect(fa, x, fason ^ 1);
     71     connect(x, gfa, gfason);
     72     update(fa), update(x);
     73 }
     74 void splay(int now, int to) {
     75     int tofa = e[to].father;
     76     while (e[now].father != tofa) {
     77         int fa = e[now].father, gfa = e[fa].father;
     78         if (gfa != tofa) {
     79             rotate(identify(now) == identify(fa) ? fa : now);
     80         }
     81         rotate(now);
     82     }
     83     if (to == root) root = now;
     84 }
     85 int kth(int rank) {
     86     int now = root;
     87     while (true) {
     88         pushdown(now);
     89         if (e[L(now)].siz >= rank) {
     90             now = L(now);
     91         } else {
     92             rank -= e[L(now)].siz + 1;
     93             if (!rank) return now;
     94             now = R(now);
     95         }
     96     }
     97 }
     98 int split(int k, int tot) {
     99     int x = kth(k), y = kth(k + tot + 1);
    100     splay(x, root), splay(y, R(x));
    101     return L(y);
    102 }
    103 void Reverse(int k, int tot) {
    104     int x = split(k, tot), y = e[x].father;
    105     if (!e[x].tag) {
    106         e[x].rev ^= 1;
    107         swap(L(x), R(x));
    108         swap(lx(x), rx(x));
    109         update(y), update(e[y].father);
    110     }
    111 }
    112 int rubbish() {
    113     if (!top) return ++cnt;
    114     int x = rub[top--];
    115     return x;
    116 }
    117 void build(int l, int r, int fa) {
    118     int mid = (l + r) / 2;
    119     int now = id[mid], pre = id[fa];
    120     if (l == r) {
    121         mx(now) = sum(now) = a[l];
    122         e[now].tag = e[now].rev = false;
    123         lx(now) = rx(now) = max(a[l], 0);
    124         e[now].siz = 1;
    125     }
    126     if (l < mid) build(l, mid - 1, mid);
    127     if (r > mid) build(mid + 1, r, mid);
    128     e[now].val = a[mid], e[now].father = pre, e[now].tag = 0;
    129     update(now);
    130     e[pre].son[mid >= fa] = now;
    131 }
    132 void Insert(int k, int tot) {
    133     for (int i = 1; i <= tot; i++) a[i] = read();
    134     for (int i = 1; i <= tot; i++) {
    135         id[i] = rubbish();
    136     }
    137     build(1, tot, 0);
    138     int z = id[(1 + tot) / 2];
    139     int x = kth(k + 1), y = kth(k + 2);
    140     splay(x, root), splay(y, R(x));
    141     connect(z, y, 0);
    142     update(y), update(x);
    143 }
    144 void remove(int x) {
    145     if (L(x)) remove(L(x));
    146     if (R(x)) remove(R(x));
    147     rub[++top] = x;
    148     e[x].father = L(x) = R(x) = e[x].tag = e[x].rev = 0;
    149 }
    150 void Erase(int k, int tot) {
    151     int x = split(k, tot), y = e[x].father;
    152     remove(x);
    153     L(y) = 0;
    154     update(y), update(e[y].father);
    155 }
    156 void change(int k, int tot, int v) {
    157     int x = split(k, tot), y = e[x].father;
    158     e[x].val = v, e[x].tag = true;
    159     sum(x) = e[x].siz * v;
    160     lx(x) = rx(x) = max(sum(x), 0);
    161     mx(x) = max(sum(x), e[x].val);
    162     update(y), update(e[y].father);
    163 }
    164 int query(int k, int tot) {
    165     int x = split(k, tot);
    166     return sum(x);
    167 }
    168 int main () {
    169     n = read(), m = read();
    170     mx(0) = a[1] = a[n + 2] = -inf;
    171     for (int i = 1; i <= n; i++) a[i + 1] = read();
    172     for (int i = 1; i <= n + 2; i++) id[i] = i;
    173     build(1, n + 2, 0);
    174     root = (n + 3) / 2;
    175     cnt = n + 2;
    176     int k, tot, v;
    177     string s;
    178     while (m--) {
    179         cin >> s;
    180         if (s != "MAX-SUM") {
    181             k = read(), tot = read();
    182         } else {
    183             printf("%d
    ", mx(root));
    184         }
    185         if (s == "INSERT") Insert(k, tot);
    186         if (s == "DELETE") Erase(k, tot);
    187         if (s == "MAKE-SAME") {
    188             v = read();
    189             change(k, tot, v);
    190         }
    191         if (s == "REVERSE") Reverse(k, tot);
    192         if (s == "GET-SUM") printf("%d
    ", query(k, tot));
    193     }
    194     return 0;
    195 }
    View Code
  • 相关阅读:
    反编译工具
    3.25Java变量
    标识符
    OMS系统
    java打印方法区别
    注释
    写代码时候要注意的两个点
    python_pracyoce_day1
    SKU和SPU
    文档注释
  • 原文地址:https://www.cnblogs.com/Sundial/p/12099076.html
Copyright © 2011-2022 走看看