BZOJ 1500 维修数列【Splay】

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

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

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

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

 #include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int N=;
const int INF=0x7fffffff;
int data[N],fa[N],id,root;
int size[N],sum[N],a[N];
int t[N][],st[N],top;
int mxl[N],mxr[N],mxm[N];
int same[N],flip[N];
void re(int x);
inline void pushup(int x){
int l=t[x][],r=t[x][];
sum[x]=sum[l]+sum[r]+data[x];
size[x]=size[l]+size[r]+;
mxl[x]=max(mxl[l],sum[l]+data[x]+max(mxl[r],));
mxr[x]=max(mxr[r],sum[r]+data[x]+max(mxr[l],));
mxm[x]=max(mxm[l],mxm[r]);
mxm[x]=max(mxm[x],max(mxr[l],)+data[x]+max(mxl[r],));
}
inline void pushdown(int x){
int l=t[x][],r=t[x][];
if(flip[x]){
flip[x]=;
swap(t[x][],t[x][]);
if(l){
flip[l]^=;
swap(mxl[l],mxr[l]);
}
if(r){
flip[r]^=;
swap(mxl[r],mxr[r]);
}
}
if(same[x]!=-INF){
if(l){
same[l]=data[l]=same[x];
sum[l]=same[l]*size[l];
mxl[l]=mxr[l]=mxm[l]=max(data[l],sum[l]);
}
if(r){
same[r]=data[r]=same[x];
sum[r]=same[r]*size[r];
mxl[r]=mxr[r]=mxm[r]=max(data[r],sum[r]);
}
same[x]=-INF;
}
}
void Rotate(int x,int w){
int y=fa[x],z=fa[y];
pushdown(y);
t[y][!w]=t[x][w];
fa[t[x][w]]=y;
fa[x]=z;
t[z][t[z][]==y]=x;
t[x][w]=y;
fa[y]=x;
pushup(y);
}
void Splay(int x,int y){
if(x!=y){
pushdown(x);
while(fa[x]!=y){
if(t[fa[x]][]==x)
Rotate(x,);
else
Rotate(x,);
}
pushup(x);
if(!y)root=x;
} }
void newnode(int &x,int y,int v){
if(top>)
x=st[top--];
else
x=++id;
flip[x]=t[x][]=t[x][]=;
mxl[x]=mxr[x]=mxm[x]=sum[x]=data[x]=v;
same[x]=-INF;
fa[x]=y;
size[x]=;
}
void build(int &x,int y,int l,int r){
if(l<=r){
int mid=(l+r)>>;
newnode(x,y,a[mid]);
build(t[x][],x,l,mid-);
build(t[x][],x,mid+,r);
pushup(x);
}
}
void init(int n){
top=root=id=;
t[][]=t[][]=fa[]=sum[]=size[]=data[]=flip[]=;
same[]=mxl[]=mxr[]=mxm[]=-INF;
newnode(root,,-INF);
newnode(t[][],,-INF);
build(t[][],,,n);
pushup();
pushup();
}
int Select(int k){
pushdown(root);
int x=root;k++;
for(;size[t[x][]]+!=k;){
if(size[t[x][]]+>k)
x=t[x][];
else
k-=size[t[x][]]+,x=t[x][];
pushdown(x);
}
return x;
}
void Insert(int c,int n){
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
int cc=Select(c+);
c=Select(c);
Splay(c,);
Splay(cc,c);
build(t[cc][],cc,,n);
pushup(cc);
pushup(c);
}
void recall(int x){
if(x){
st[++top]=x;
recall(t[x][]);
recall(t[x][]);
}
}
void Delete(int l,int r){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
recall(t[r][]);
t[r][]=;
pushup(r);
pushup(l);
}
void Flip(int l,int r){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
flip[t[r][]]^=;
swap(mxl[t[r][]],mxr[t[r][]]);
}
void Same(int l,int r,int v){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
int x=t[r][];
same[x]=data[x]=v;
sum[x]=data[x]*size[x];
mxl[x]=mxr[x]=mxm[x]=max(v,sum[x]);
pushup(r);
pushup(l);
}
int Sum(int l,int r){
r=Select(r+);
l=Select(l-);
Splay(l,);
Splay(r,l);
return sum[t[r][]];
}
int Max(int l,int r){
l=Select(l-),r=Select(r+);
Splay(l,),Splay(r,l);
return mxm[t[r][]];
}
void de(){
for(int i=;i<=id;i++){
printf("%d %d %d %d %d++\n",i,t[i][],t[i][],sum[i],mxm[i]);
}
}
void re(int x){
if(x){
re(t[x][]);
printf("%d ",data[x]);
re(t[x][]);
}
}
int main(){
int n,m,i,p,cnt,v;
char op[];
while(scanf("%d%d",&n,&m)!=EOF){
for(i=;i<=n;i++) scanf("%d",&a[i]);
init(n);
//de();
while(m--){
scanf("%s",op);
if(!strcmp(op,"GET-SUM")){
scanf("%d%d",&p,&cnt);
printf("%d\n",Sum(p,p+cnt-));
}
if(!strcmp(op,"MAX-SUM")){
printf("%d\n",Max(,size[root]-));
}
if(!strcmp(op,"INSERT")){
scanf("%d%d",&p,&cnt);
Insert(p,cnt);
}
if(!strcmp(op,"DELETE")){
scanf("%d%d",&p,&cnt);
Delete(p,p+cnt-);
}
if(!strcmp(op,"MAKE-SAME")){
scanf("%d%d%d",&p,&cnt,&v);
Same(p,p+cnt-,v);
}
if(!strcmp(op,"REVERSE")){
scanf("%d%d",&p,&cnt);
Flip(p,p+cnt-);
}
}
}
return ;
}
/*
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
*/
上一篇:Java异常基础Exception


下一篇:GO基础知识分享