①学会了维护最大连续子序列,跟最长全0连续子序列其实差不多;我一开始做麻烦了(用了前缀和。。)。
一些需要注意的细节:
②插入新节点的时候要注意维护其儿子节点的父指针;
③pushdown的位置不是随便放的,它应该放在对该节点进行询问之前。
④覆盖标记应该设为无穷,而不是0;因为0也可能是需要覆盖的。
⑤翻转标记应该使用^=标记,而不是=。
#include<iostream>
using namespace std;
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
struct SS{
SS * f,* c[2];
bool is_root;
int size,data,sum,lmax,rmax,max;
int lazy;
bool flag;
}*nil=new SS((SS){nil,nil,nil,0,0,0,0,-1E7,-1E7,-1E7}),*root=new SS((SS){nil,nil,nil,1,2,-1E6,-2E6,-1E6,-1E6,-1E6});
int T;
inline void Out(SS * x){
//printf("%d(%d) ",x->data,T++);
cout<<"("<<x->f->data<<")"<<x->data<<":"<<x->size<<"(Size) "<<x->sum<<"(Sum) "<<x->lmax<<"(Lmax) "<<x->rmax<<"(Rmax) "<<x->max<<"(Max)\n";
}
inline void mtn(SS * x){
x->size=x->c[0]->size+x->c[1]->size+1;
x->sum=x->c[0]->sum+x->c[1]->sum+x->data;
x->lmax=max(x->c[0]->lmax,max(x->c[0]->sum+x->data,x->c[0]->sum+x->data+x->c[1]->lmax));
x->rmax=max(x->c[1]->rmax,max(x->c[1]->sum+x->data,x->c[1]->sum+x->data+x->c[0]->rmax));
x->max=max(x->data,max(x->lmax,max(x->rmax,max(x->c[0]->rmax+x->data,max(x->c[0]->rmax+x->data+x->c[1]->lmax,max(x->data+x->c[1]->lmax,max(x->c[0]->max,x->c[1]->max)))))));
}
inline void re_paint(SS * x){
if(x!=nil){
swap(x->c[0],x->c[1]);
swap(x->lmax,x->rmax);
x->flag^=1;
}
}
inline void sa_paint(SS * x,int A){
if(x!=nil){
x->data=A;
x->sum=A*x->size;
x->lazy=A;
if(A<0)x->lmax=x->rmax=x->max=A;
else x->lmax=x->rmax=x->max=A*x->size;
}
}
inline void pushdown(SS * x){
if(x->flag){
re_paint(x->c[0]);
re_paint(x->c[1]);
x->flag=0;
}
if(x->lazy!=-0x7fffffff){
sa_paint(x->c[0],x->lazy);
sa_paint(x->c[1],x->lazy);
x->lazy=-0x7fffffff;
}
}
inline void out(SS * x){
if(x==nil)return;
pushdown(x);
out(x->c[0]);
Out(x);
out(x->c[1]);
}
inline void zig(SS * x,bool D){
SS * ftr=x->f;
x->f=ftr->f;
//cout<<x->data<<"->"<<x->c[0]->data<<" "<<x->c[1]->data<<"------>"<<ftr->data<<"->"<<ftr->c[0]->data<<" "<<ftr->c[1]->data<<endl;
if(ftr->is_root)ftr->is_root=0,x->is_root=1;
if(x->f->c[1]==ftr)x->f->c[1]=x;
else x->f->c[0]=x;
ftr->c[D]=x->c[!D];
ftr->c[D]->f=ftr;
x->c[!D]=ftr;
ftr->f=x;
mtn(ftr);
//cout<<"Zig:"<<x->data<<"->"<<x->c[0]->data<<" "<<x->c[1]->data<<"------>"<<ftr->data<<"->"<<ftr->c[0]->data<<" "<<ftr->c[1]->data<<endl;
}
inline void splay(SS * x){
/*cout<<"S:";
out(root);*/
for(bool D;!x->is_root;zig(x,D)){
D=x->f->c[1]==x;
if(!x->f->is_root&&D==(x->f->f->c[1]==x->f))zig(x->f,D);
}
root=x;
mtn(x);/*
cout<<"Play\n";
out(root);
cout<<"\n";*/
}
inline void search(SS * x,int A){
//cout<<x->data<<endl;
pushdown(x);
while(x->c[0]->size!=A-1){
//cout<<"Search:"<<x->data<<","<<A<<"("<<x->size<<")"<<x->c[0]->data<<"("<<x->c[0]->size<<")\n";
if(x->c[0]->size>=A)x=x->c[0];
else A-=x->c[0]->size+1,x=x->c[1];
pushdown(x);
}
splay(x);
}
inline void open(int l,int L){//(l,r)
//cout<<"Open:"<<l<<"->"<<L<<endl;
search(root,l);
//out(root);
root=root->c[1];
root->is_root=1;
search(root,L+1);
}
inline void close(){
mtn(root);
root->is_root=0;
root=root->f;
mtn(root);
}
char * ptr=(char *)malloc(30000000);
inline int in(){
bool flag=0;
while(*ptr<'0'||*ptr>'9')
if(*ptr++=='-')
flag=1;
int x=0;
while(*ptr>47&&*ptr<58)x=x*10+*ptr++-'0';
if(flag)return -x;
return x;
}
int main(){
freopen("seq2005.in","r",stdin);
freopen("seq2005.out","w",stdout);
root->c[0]=new SS((SS){root,nil,nil,0,1,-1E6,-1E6,-1E6,-1E6,-1E6});
root->lazy=-0x7fffffff;
root->c[0]->lazy=-0x7fffffff;
fread(ptr,1,30000000,stdin);
SS * tmp;
open(1,0);
int posi,tot=in(),M=in(),c;
while(tot--){
root->c[0]=new SS((SS){root,root->c[0],nil,0,0,in()});
root->c[0]->c[0]->f=root->c[0];
root->c[0]->lazy=-0x7fffffff;
mtn(root->c[0]);
}
close();
while(M--){
while(*ptr<'A'||*ptr>'Z')++ptr;
ptr+=2;
switch(*ptr){
case 'S':
posi=in()+1,tot=in();
open(posi,0);
while(tot--){
root->c[0]=new SS((SS){root,root->c[0],nil,0,0,in()});
root->c[0]->c[0]->f=root->c[0];
root->c[0]->lazy=-0x7fffffff;
mtn(root->c[0]);
}
close();
break;
case 'L':
posi=in(),tot=in();
open(posi,tot);
root->c[0]=nil;
close();
break;
case 'K':
ptr+=4;
posi=in(),tot=in();
open(posi,tot);
sa_paint(root->c[0],in());
close();
break;
case 'V':
posi=in(),tot=in();
open(posi,tot);
re_paint(root->c[0]);
close();
break;
case 'T':
ptr+=2;
posi=in(),tot=in();
open(posi,tot);
printf("%d\n",root->c[0]->sum);
close();
break;
case 'X':
ptr+=5;
printf("%d\n",root->max);
break;
}/*
cout<<M<<":";
T=0;
out(root);
cout<<endl;*/
}
}