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

    Description

    Input

    输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。以下M行,每行一条命令,格式参见问题描述中的表格。

    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

    Source

    这题也是醉了~拍了两三天。。。看上去也就是个splay裸题。
    最大字段和的维护:splay每个节点i记录从i的左子树最左起的最大字段和lb,右子树最右起的最大字段和rb,以及它所表示的整个区间的最大字段和。 lb[i]=max(lb[lc],sum[lc]+key[i]+lb[rc]),rb[i]=max(rb[rc],sum[rc]+key[i]+rb[lc]),wb[i]=max(wb[lc],wb[rc],rb[lc]+lb[rc]+key[i]),其中sum表示区间和,key表示该点的权值,lc与rc分别表示左右孩子。有许多细节请自己脑补。。。
      1 #include<queue>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 #include<cstdlib>
      6 using namespace std;
      7 
      8 #define maxn 500010
      9 #define inf (1 << 20)
     10 int n,m,TEMP[maxn],stack[maxn];
     11 queue <int> team;
     12 
     13 inline int Max(int a,int b) {if (a > b) return a; return b;}
     14 
     15 struct node
     16 {
     17     int fa[maxn],ch[maxn][2],key[maxn],sum[maxn],lm[maxn],rm[maxn],wm[maxn],size[maxn],cnt,root;
     18     bool rev[maxn],change[maxn];
     19 
     20     inline int newnode()
     21     {
     22         if (team.empty()) return ++cnt;
     23         int ret = team.front(); team.pop();
     24         return ret;
     25     }
     26 
     27     inline void updata(int a)
     28     {
     29         int lc = ch[a][0],rc = ch[a][1];
     30         pushdown(a); pushdown(lc); pushdown(rc);
     31         size[a] = size[lc] + size[rc] + 1;
     32         {
     33             sum[a] = sum[lc] + sum[rc] + key[a];
     34             lm[a] = rm[a] = wm[a] = -inf;
     35             lm[a] = Max(lm[a],sum[lc]+key[a]);
     36             lm[a] = Max(lm[a],sum[lc]+lm[rc]+key[a]);
     37             if (lc) lm[a] = Max(lm[a],lm[lc]);
     38             rm[a] = Max(rm[a],sum[rc]+key[a]);
     39             rm[a] = Max(rm[a],sum[rc]+rm[lc]+key[a]);
     40             if (rc) rm[a] = Max(rm[a],rm[rc]);
     41             wm[a] = Max(lm[a],rm[a]);
     42             wm[a] = Max(wm[a],rm[lc]+lm[rc]+key[a]);
     43             wm[a] = Max(wm[a],key[a]);
     44             wm[a] = Max(wm[a],rm[lc]+key[a]);
     45             wm[a] = Max(wm[a],lm[rc]+key[a]);
     46             if (rc) wm[a] = Max(wm[a],Max(lm[rc],wm[rc]));
     47             if (lc) wm[a] = Max(wm[a],Max(rm[lc],wm[lc]));
     48         }
     49     }
     50     
     51     inline void pushdown(int a)
     52     {
     53         if (a == 0) { rev[a] = false; change[a] = false; return; }
     54         else
     55         {
     56             int lc = ch[a][0],rc = ch[a][1];
     57             if (rev[a])
     58             {
     59                 rev[a] = false;
     60                 swap(lm[a],rm[a]); swap(ch[a][0],ch[a][1]);
     61                 if (lc) rev[lc] ^= 1; if (rc) rev[rc] ^= 1;
     62             }
     63             if (change[a])
     64             {
     65                 change[a] = false;
     66                 if (lc) key[lc] = key[a],change[lc] = true;
     67                 if (rc) key[rc] = key[a],change[rc] = true;
     68                 sum[a] = key[a] * size[a];
     69                 if (key[a] >= 0) wm[a] = lm[a] = rm[a] = sum[a];
     70                 else wm[a] = lm[a] = rm[a] = key[a];
     71             }
     72         }
     73     }
     74     
     75     inline int find(int rank,int have,int now)
     76     {
     77         pushdown(now);
     78         if (have+size[ch[now][0]]+1==rank) return now;
     79         if (have+size[ch[now][0]]+1>rank) return find(rank,have,ch[now][0]);
     80         else return find(rank,have+size[ch[now][0]]+1,ch[now][1]);
     81     }
     82     
     83     inline void rotate(int x)
     84     {
     85         int y = fa[x],z = fa[y],l,r;
     86         if (ch[y][0] == x) l = 0; else l = 1; r = l ^ 1;
     87         if (z != 0)
     88         {
     89             if (ch[z][0] == y) ch[z][0] = x; else ch[z][1] = x;
     90         }
     91         fa[x] = z; fa[y] = x; fa[ch[x][r]] = y;
     92         ch[y][l] = ch[x][r]; ch[x][r] = y;
     93         updata(y); updata(x);
     94     }
     95     
     96     inline void splay(int x,int aim)
     97     {
     98         int t = fa[aim],top = 0;
     99         for (int i = x;i != t;i = fa[i]) stack[++top] = i;
    100         while (top) pushdown(stack[top--]);
    101         while (fa[x] != t)
    102         {
    103             int y = fa[x],z = fa[y];
    104             if (fa[y] != t)
    105             {
    106                 if ((ch[y][0] == x)^(ch[z][0] == y)) rotate(x);
    107                 else rotate(y);
    108             }
    109             rotate(x);
    110         }
    111         if (aim == root) root = x;
    112     }
    113     
    114     inline int build(int l,int r)
    115     {
    116         int now = newnode(),mid = (l + r) >> 1;
    117         ch[now][0] = ch[now][1] = 0;
    118         rev[now] = change[now] = false;
    119         if (l == r)
    120         {
    121             key[now] = TEMP[l]; updata(now);
    122             return now;
    123         }
    124         if (l < mid)
    125         {
    126             ch[now][0] = build(l,mid - 1);
    127             fa[ch[now][0]] = now;
    128         }
    129         if (mid < r)
    130         {
    131             ch[now][1] = build(mid + 1,r);
    132             fa[ch[now][1]] = now;
    133         }
    134         key[now] = TEMP[mid];
    135         updata(now);
    136         return now;
    137     }
    138     
    139     inline void init(int l,int r)
    140     {
    141         root = build(l,r); int p; 
    142         p = find(n,0,root);
    143         splay(p,root);
    144         key[++cnt] = -inf;
    145         fa[cnt] = p; ch[p][1] = cnt;
    146         updata(cnt); updata(p);
    147         p = find(1,0,root);
    148         splay(p,root);
    149         key[++cnt] = -inf;
    150         fa[cnt] = p; ch[p][0] = cnt;
    151         updata(cnt); updata(p);
    152     }
    153     
    154     inline void insert(int a,int b)
    155     {
    156         int p = find(a + 1,0,root),q = find(a + 2,0,root);
    157         splay(p,root); splay(q,ch[p][1]);
    158         int tr = build(1,b);
    159         fa[tr] = q; ch[q][0] = tr;
    160         updata(q); updata(p);
    161     }
    162 
    163     inline void rec(int now)
    164     {
    165         if (now == 0) return;
    166         team.push(now);
    167         rec(ch[now][0]); rec(ch[now][1]);
    168     }
    169     
    170     inline void del(int a,int b)
    171     {
    172         int p = find(a,0,root),q = find(a+b+1,0,root);
    173         splay(p,root); splay(q,ch[p][1]);
    174         rec(ch[q][0]);
    175         fa[ch[q][0]] = 0; ch[q][0] = 0;
    176         updata(q); updata(p);
    177     }
    178     
    179     inline void reverse(int a,int b)
    180     {
    181         int p = find(a,0,root),q = find(a+b+1,0,root);
    182         splay(p,root); splay(q,ch[p][1]);
    183         rev[ch[q][0]] ^= 1; pushdown(ch[q][0]);
    184         updata(q); updata(p);
    185     }
    186     
    187     inline int getsum(int a,int b)
    188     {
    189         int p = find(a,0,root),q = find(a+b+1,0,root);
    190         splay(p,root); splay(q,ch[p][1]);
    191         return sum[ch[q][0]];
    192     }
    193 
    194     inline int maxsum() { updata(root); return wm[root];}
    195 
    196     inline void modify(int a,int b,int c)
    197     {
    198         int p = find(a,0,root),q = find(a+b+1,0,root);
    199         splay(p,root); splay(q,ch[p][1]);
    200         key[ch[q][0]] = c; change[ch[q][0]] = true;
    201         pushdown(ch[q][0]);
    202         updata(ch[q][0]); updata(q); updata(p);
    203         return;
    204     }
    205 }tree;
    206 
    207 inline int read()
    208 {
    209     int x=0,f=1;char ch=getchar();
    210     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    211     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    212     return x*f;
    213 }
    214 
    215 int main()
    216 {
    217     freopen("1500.in","r",stdin);
    218     freopen("1500.out","w",stdout);
    219     n = read(); m = read();
    220     for (int i = 1;i <= n;++i) TEMP[i] = read();
    221     tree.init(1,n);
    222     char opt[20];
    223     while (m--)
    224     {
    225         scanf("%s",opt);
    226         if (opt[0] == 'I')
    227         {
    228             int a = read(),b = read();
    229             for (int i = 1;i <= b;++i) TEMP[i] = read();
    230             tree.insert(a,b);
    231         }
    232         else if (opt[0] == 'D')
    233         {
    234             int a = read(),b =read();
    235             tree.del(a,b);
    236         }
    237         else if (opt[0] == 'R')
    238         {
    239             int a = read(),b = read();
    240             tree.reverse(a,b);
    241         }
    242         else if (opt[0] == 'G')    
    243         {
    244             int a = read(),b = read();
    245             printf("%d
    ",tree.getsum(a,b));
    246         }
    247         else if (opt[0] == 'M'&&opt[2] == 'K')
    248         {
    249             int a = read(),b = read(),c = read();
    250             tree.modify(a,b,c);
    251         }
    252         else printf("%d
    ",tree.maxsum());
    253     }
    254     fclose(stdin); fclose(stdout);
    255     return 0;
    256 }
    View Code
     
  • 相关阅读:
    【剑指offer】不使用新变量,交换两个变量的值,C++实现
    【剑指offer】不用加减乘除做加法,C++实现
    【剑指offer】求1+2+…+n,C++实现
    【剑指offer】左旋转字符串,C+实现
    给记事本添加接口,并通过菜单来执行自定义的功能
    修改PE文件的入口函数OEP
    360搜集隐私程序员级分析,供方舟子及大众参考
    Android窃取用户信息新思路
    如何整治那些敢偷用你Wi-Fi的人
    保护WIFI无线网络的安全
  • 原文地址:https://www.cnblogs.com/mmlz/p/4294485.html
Copyright © 2011-2022 走看看