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

    注意:1,内存限制,所以需要回收删除的点

       2,当前节点的左连续区间和最大值=max(左子树的左连续区间和最大值,左子树的总和+当节点的值+max(右子树的左连续区间和最大值,0));右连续区间和最大值同理

         当前节点的区间和最大值=max(左子树的区间和最大值,max(右子树的区间和最大值,max(左子树的右连续区间和最大值,0)+max(右子树的左连续区间和最大值,0)+当前节点的值))

       3,pushdown时,应该交换左子树的左连续区间和最大值与左子树的右连续区间和最大值。因为向上更新时这两个值的不同对结果有影响,不能延迟更新。

      1 #include<stdio.h> 
      2 #include<string.h>
      3 #include<iostream>
      4 using namespace std;
      5 const int N=500100;
      6 const int INF=0x7fffffff;
      7 int data[N],fa[N],id,root; 
      8 int size[N],sum[N],a[N];
      9 int t[N][2],st[N],top;
     10 int mxl[N],mxr[N],mxm[N];
     11 int same[N],flip[N];
     12 void re(int x);
     13 inline void pushup(int x){
     14     int l=t[x][0],r=t[x][1];
     15     sum[x]=sum[l]+sum[r]+data[x];
     16     size[x]=size[l]+size[r]+1;
     17     mxl[x]=max(mxl[l],sum[l]+data[x]+max(mxl[r],0));
     18     mxr[x]=max(mxr[r],sum[r]+data[x]+max(mxr[l],0));
     19     mxm[x]=max(mxm[l],mxm[r]); 
     20     mxm[x]=max(mxm[x],max(mxr[l],0)+data[x]+max(mxl[r],0));
     21 }
     22 inline void pushdown(int x){
     23     int l=t[x][0],r=t[x][1];
     24     if(flip[x]){
     25         flip[x]=0;
     26         swap(t[x][0],t[x][1]);
     27         if(l){
     28             flip[l]^=1;
     29             swap(mxl[l],mxr[l]);
     30         }
     31         if(r){
     32             flip[r]^=1;
     33             swap(mxl[r],mxr[r]);
     34         }
     35     }
     36     if(same[x]!=-INF){
     37         if(l){
     38             same[l]=data[l]=same[x];
     39             sum[l]=same[l]*size[l];
     40             mxl[l]=mxr[l]=mxm[l]=max(data[l],sum[l]);
     41         }
     42         if(r){
     43             same[r]=data[r]=same[x];
     44             sum[r]=same[r]*size[r];
     45             mxl[r]=mxr[r]=mxm[r]=max(data[r],sum[r]);
     46         }
     47         same[x]=-INF;
     48     }
     49 }
     50 void Rotate(int x,int w){
     51     int y=fa[x],z=fa[y];
     52     pushdown(y);
     53     t[y][!w]=t[x][w];
     54     fa[t[x][w]]=y;
     55     fa[x]=z;
     56     t[z][t[z][1]==y]=x;
     57     t[x][w]=y;
     58     fa[y]=x;
     59     pushup(y);
     60 }
     61 void Splay(int x,int y){
     62     if(x!=y){
     63         pushdown(x);
     64         while(fa[x]!=y){
     65             if(t[fa[x]][0]==x)
     66                 Rotate(x,1);
     67             else
     68                 Rotate(x,0);
     69         }
     70         pushup(x);
     71         if(!y)root=x;
     72     }
     73     
     74 }
     75 void newnode(int &x,int y,int v){
     76     if(top>0)
     77         x=st[top--];
     78     else
     79         x=++id;
     80     flip[x]=t[x][0]=t[x][1]=0;
     81     mxl[x]=mxr[x]=mxm[x]=sum[x]=data[x]=v;
     82     same[x]=-INF;
     83     fa[x]=y;
     84     size[x]=1;
     85 }
     86 void build(int &x,int y,int l,int r){
     87     if(l<=r){
     88         int mid=(l+r)>>1;
     89         newnode(x,y,a[mid]);
     90         build(t[x][0],x,l,mid-1);
     91         build(t[x][1],x,mid+1,r);
     92         pushup(x);
     93     }
     94 }
     95 void init(int n){
     96     top=root=id=0;
     97     t[0][0]=t[0][1]=fa[0]=sum[0]=size[0]=data[0]=flip[0]=0;
     98     same[0]=mxl[0]=mxr[0]=mxm[0]=-INF;
     99     newnode(root,0,-INF);
    100     newnode(t[1][1],1,-INF);
    101     build(t[2][0],2,1,n);
    102     pushup(2);
    103     pushup(1);
    104 }
    105 int Select(int k){
    106     pushdown(root);
    107     int x=root;k++;
    108     for(;size[t[x][0]]+1!=k;){
    109         if(size[t[x][0]]+1>k)
    110             x=t[x][0];
    111         else
    112             k-=size[t[x][0]]+1,x=t[x][1];
    113         pushdown(x); 
    114     }
    115     return x;
    116 }
    117 void Insert(int c,int n){
    118     for(int i=1;i<=n;i++){
    119         scanf("%d",&a[i]);
    120     }
    121     int cc=Select(c+1);
    122     c=Select(c);
    123     Splay(c,0);
    124     Splay(cc,c);
    125     build(t[cc][0],cc,1,n);
    126     pushup(cc);
    127     pushup(c);
    128 }
    129 void recall(int x){
    130     if(x){
    131         st[++top]=x;
    132         recall(t[x][0]);
    133         recall(t[x][1]);
    134     }
    135 }
    136 void Delete(int l,int r){
    137     r=Select(r+1);
    138     l=Select(l-1);
    139     Splay(l,0);
    140     Splay(r,l);
    141     recall(t[r][0]);
    142     t[r][0]=0;
    143     pushup(r);
    144     pushup(l);
    145 }
    146 void Flip(int l,int r){
    147     r=Select(r+1);
    148     l=Select(l-1);
    149     Splay(l,0);
    150     Splay(r,l);
    151     flip[t[r][0]]^=1;
    152     swap(mxl[t[r][0]],mxr[t[r][0]]);
    153 }
    154 void Same(int l,int r,int v){
    155     r=Select(r+1);
    156     l=Select(l-1);
    157     Splay(l,0);
    158     Splay(r,l);
    159     int x=t[r][0];
    160     same[x]=data[x]=v;
    161     sum[x]=data[x]*size[x];
    162     mxl[x]=mxr[x]=mxm[x]=max(v,sum[x]);
    163     pushup(r);
    164     pushup(l);
    165 } 
    166 int Sum(int l,int r){
    167     r=Select(r+1);
    168     l=Select(l-1);
    169     Splay(l,0);
    170     Splay(r,l);
    171     return sum[t[r][0]];
    172 }
    173 int Max(int l,int r){
    174     l=Select(l-1),r=Select(r+1);
    175     Splay(l,0),Splay(r,l);
    176     return mxm[t[r][0]];
    177 }
    178 void de(){
    179     for(int i=1;i<=id;i++){
    180         printf("%d %d %d %d %d++
    ",i,t[i][0],t[i][1],sum[i],mxm[i]);
    181     }
    182 }
    183 void re(int x){
    184     if(x){
    185         re(t[x][0]);
    186         printf("%d ",data[x]);
    187         re(t[x][1]);
    188     }
    189 }
    190 int main(){
    191     int n,m,i,p,cnt,v;
    192     char op[20];
    193     while(scanf("%d%d",&n,&m)!=EOF){
    194         for(i=1;i<=n;i++)    scanf("%d",&a[i]);
    195         init(n);
    196         //de();
    197         while(m--){
    198             scanf("%s",op);
    199             if(!strcmp(op,"GET-SUM")){
    200                 scanf("%d%d",&p,&cnt);
    201                 printf("%d
    ",Sum(p,p+cnt-1));
    202             }
    203             if(!strcmp(op,"MAX-SUM")){
    204                 printf("%d
    ",Max(1,size[root]-2));
    205             }
    206             if(!strcmp(op,"INSERT")){
    207                 scanf("%d%d",&p,&cnt);
    208                 Insert(p,cnt);
    209             }
    210             if(!strcmp(op,"DELETE")){
    211                 scanf("%d%d",&p,&cnt);
    212                 Delete(p,p+cnt-1);
    213             }
    214             if(!strcmp(op,"MAKE-SAME")){
    215                 scanf("%d%d%d",&p,&cnt,&v);
    216                 Same(p,p+cnt-1,v);
    217             }
    218             if(!strcmp(op,"REVERSE")){
    219                 scanf("%d%d",&p,&cnt);
    220                 Flip(p,p+cnt-1);
    221             }
    222         }
    223     }
    224     return 0;
    225 }
    226 /*
    227 9 8
    228 
    229 2 -6 3 5 1 -5 -3 6 3
    230 
    231 GET-SUM 5 4
    232 
    233 MAX-SUM
    234 
    235 INSERT 8 3 -5 7 2
    236 
    237 DELETE 12 1
    238 
    239 MAKE-SAME 3 3 2
    240 
    241 REVERSE 3 6
    242 
    243 GET-SUM 5 4
    244 
    245 MAX-SUM
    246 */
  • 相关阅读:
    显示磁盘信息
    给VG增加磁盘,给文件目录增加空间
    第8.11节 Python类中记录实例变量属性的特殊变量__dict__
    Python中format_map与format字符串格式化的区别
    生成器函数与函数的区别
    什么是Python生成器?与迭代器的关系是什么?
    第8.10节 使用__class__查看Python中实例对应的类
    Python运算符的优先级是怎样的?
    Python怎么控制将一个整数输出成指定长的十六进制数?
    Python中函数的参数带星号是什么意思?
  • 原文地址:https://www.cnblogs.com/L-King/p/5705193.html
Copyright © 2011-2022 走看看