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++\n",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\n",Sum(p,p+cnt-1)); 202 } 203 if(!strcmp(op,"MAX-SUM")){ 204 printf("%d\n",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 */