zoukankan      html  css  js  c++  java
  • BZOJ 1500 维修数列

    维修数列

    【问题描述】

    【输入格式】

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

    【输出格式】

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

    【样例输入】

    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

    【样例输出】

    -1
    10
    1
    10

    【数据范围】


    题解:

    每一个操作都差不多是将通过将左右区间(开区间)端点转到根和右孩子

    就能将整个区间转移到根的右孩子的左孩子的子树,就能直接取出信息了

      1 #include<cmath>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<algorithm>
      7 using namespace std;
      8 const int maxn = 1e6;
      9 const int inf = 2e9;
     10 inline void Scan(int &x)
     11 {
     12     char c;
     13     bool o = false;
     14     while(!isdigit(c = getchar())) o = (c != '-') ? o : true;
     15     x = c - '0';
     16     while(isdigit(c = getchar())) x = x * 10 + c - '0';
     17     if(o) x = -x;
     18 }
     19 int n, m;
     20 int num;
     21 int root;
     22 int deln;
     23 int del[maxn];
     24 int id[maxn], pri[maxn];
     25 int lc[maxn], rc[maxn], fat[maxn];
     26 int si[maxn], sum[maxn], val[maxn], lmax[maxn], rmax[maxn], kmax[maxn];
     27 int sam[maxn];
     28 bool rev[maxn];
     29 inline void Update(int x)
     30 {
     31     int l = lc[x], r = rc[x];
     32     si[x] = si[l] + si[r] + 1;
     33     sum[x] = sum[l] + sum[r] + val[x];
     34     lmax[x] = max(lmax[l], sum[l] + val[x] + max(lmax[r], 0));
     35     rmax[x] = max(rmax[r], sum[r] + val[x] + max(rmax[l], 0));
     36     kmax[x] = max(kmax[l], kmax[r]);
     37     kmax[x] = max(kmax[x], rmax[l] + lmax[r] + val[x]);
     38     kmax[x] = max(kmax[x], max(max(rmax[l], lmax[r]), 0) + val[x]);
     39 }
     40 inline void Change(int x, int c)
     41 {
     42     sam[x] = val[x] = c;
     43     sum[x] = si[x] * c;
     44     kmax[x] = lmax[x] = rmax[x] = c > 0 ? sum[x] : c;
     45 }
     46 inline void Rever(int x)
     47 {
     48     rev[x] ^= 1;
     49     swap(lmax[x], rmax[x]);
     50     swap(lc[x], rc[x]);
     51 }
     52 inline void Down(int x)
     53 {
     54     int l = lc[x], r = rc[x];
     55     if(rev[x])
     56     {
     57         Rever(l), Rever(r);
     58         rev[x] = 0;
     59     }
     60     if(sam[x] != inf)
     61     {
     62         Change(l, sam[x]), Change(r, sam[x]);
     63         sam[x] = inf;
     64     }
     65 }
     66 inline void Printtree(int k)
     67 {
     68     if(!k) return;
     69     Down(k);
     70     printf("k=%d v=%d lc=%d rc=%d si=%d sum=%d
    ", k, val[k], lc[k], rc[k], si[k], sum[k]);
     71     Printtree(lc[k]);
     72     Printtree(rc[k]);
     73 }
     74 void Print(int k)
     75 {
     76     if(!k) return;
     77     Down(k);
     78     Print(lc[k]);
     79     printf("%d ", val[k]);
     80     Print(rc[k]);
     81 }
     82 inline void Turn(int x)
     83 {
     84     int y = fat[x], z = fat[y];
     85     int w = (lc[y] != x) ? lc[x] : rc[x];
     86     Down(y), Down(x);
     87     fat[y] = x;
     88     fat[x] = z;
     89     if(w) fat[w] = y;
     90     if(z)
     91         if(lc[z] == y) lc[z] = x;
     92         else rc[z] = x;
     93     if(lc[y] == x) rc[x] = y, lc[y] = w;
     94     else lc[x] = y, rc[y] = w;
     95     Update(y);
     96 }
     97 inline void Splay(int x, int anc)
     98 {
     99     Down(x);
    100     while(fat[x] != anc)
    101     {
    102         if(fat[fat[x]] != anc)
    103             if((lc[fat[fat[x]]] == fat[x]) == (lc[fat[x]] == x)) Turn(fat[x]);
    104             else Turn(x);
    105         Turn(x);
    106     }
    107     Update(x);
    108     if(!anc) root = x;
    109 }
    110 int Build(int l, int r, int f)
    111 {
    112     int mid = l + r >> 1;
    113     int k = id[mid];
    114     fat[k] = f;
    115     sam[k] = inf;
    116     val[k] = pri[mid];
    117     if(l == r) si[k] = 1;
    118     if(l < mid) lc[k] = Build(l, mid - 1, k);
    119     if(r > mid) rc[k] = Build(mid + 1, r, k);
    120     Update(k);
    121     return k;
    122 }
    123 inline int Find(int x)
    124 {
    125     int k = root;
    126     while(true)
    127     {
    128         Down(k);
    129         int sum = si[lc[k]] + 1;
    130         if(sum == x) return k;
    131         if(sum > x) k = lc[k];
    132         else k = rc[k], x -= sum;
    133     }
    134 }
    135 inline void Clear(int x)
    136 {
    137     lc[x] = rc[x] = fat[x] = 0;
    138     rev[x] = 0, sam[x] = inf;
    139 }
    140 inline void Modify(int l, int r, int c)
    141 {
    142     int x = Find(l), y = Find(r);
    143     Splay(x, 0), Splay(y, x);
    144     int z = lc[y];
    145     Change(z, c);
    146     Update(y), Update(x);
    147 }
    148 inline void Insert(int l, int r, int n)
    149 {
    150     int x = Find(l), y = Find(r);
    151     Splay(x, 0), Splay(y, x);
    152     int cnt = n;
    153     while(deln && cnt) id[cnt--] = del[deln--];
    154     while(cnt) id[cnt--] = ++num;
    155     int np = Build(1, n, 0);
    156     Down(y);
    157     lc[y] = np;
    158     fat[np] = y;
    159     Update(y), Update(x);
    160 }
    161 void Del(int x)
    162 {
    163     if(!x) return;
    164     Del(lc[x]);
    165     del[++deln] = x;
    166     Del(rc[x]);
    167     Clear(x);
    168 }
    169 inline void Del(int l, int r)
    170 {
    171     int x = Find(l), y = Find(r);
    172     Splay(x, 0), Splay(y, x);
    173     int z = lc[y];
    174     lc[y] = 0;
    175     Del(z);
    176     Update(y), Update(x);
    177 }
    178 inline void Reverse(int l, int r)
    179 {
    180     int x = Find(l), y = Find(r);
    181     Splay(x, 0), Splay(y, x);
    182     int z = lc[y];
    183     Rever(z);
    184     Update(y), Update(x);
    185 }
    186 inline void Sum(int l, int r)
    187 {
    188     int x = Find(l), y = Find(r);
    189     Splay(x, 0), Splay(y, x);
    190     int z = lc[y];
    191     printf("%d
    ", sum[z]);
    192 }
    193 inline void Max(int l, int r)
    194 {
    195     int x = Find(l), y = Find(r);
    196     Splay(x, 0), Splay(y, x);
    197     int z = lc[y];
    198     printf("%d
    ", kmax[z]);
    199 }
    200 char s[233];
    201 int main()
    202 {
    203     Scan(n), Scan(m);
    204     num = n + 2;
    205     for(int i = 1; i <= n; ++i) Scan(pri[i + 1]);
    206     for(int i = 1; i <= num; ++i) id[i] = i;
    207     root = Build(1, num, 0);
    208     int pos, tot, c, l, r;
    209     while(m--)
    210     {
    211         scanf("%s", s);
    212         switch(s[0])
    213         {
    214             case 'I':
    215             {
    216                 Scan(pos), Scan(tot);
    217                 for(int i = 1; i <= tot; ++i) Scan(pri[i]);
    218                 Insert(pos + 1, pos + 2, tot);
    219                 break;
    220             }
    221             case 'D':
    222             {
    223                 Scan(pos), Scan(tot);
    224                 Del(pos, pos + tot + 1);
    225                 break;
    226             }
    227             case 'R':
    228             {
    229                 Scan(pos), Scan(tot);
    230                 Reverse(pos, pos + tot + 1);
    231                 break;
    232             }
    233             case 'G':
    234             {
    235                 Scan(pos), Scan(tot);
    236                 Sum(pos, pos + tot + 1);
    237                 break;
    238             }
    239             case 'M':
    240             {
    241                 if(s[4] == '-')
    242                 {
    243                     Scan(pos), Scan(tot), Scan(c);
    244                     Modify(pos, pos + tot + 1, c);
    245                 }
    246                 else Max(1, si[root]);
    247                 break;
    248             }
    249         }
    250     }
    251 }
  • 相关阅读:
    点到圆的切点
    两圆交点
    问n条平行于x,y的直线交点个数
    凸包与直线的关系
    Kuangbin的计算几何模板
    最大空凸包
    树链剖分模板题
    笔记1
    面试题2
    python utf-8 转码问题
  • 原文地址:https://www.cnblogs.com/lytccc/p/6899321.html
Copyright © 2011-2022 走看看