这是一个Splay模板题,适合用来连代码能力
对于翻转操作,可以加入一个布尔值标记flip,对于最大连续子段和,可以维护三个标记:maxl,maxr,maxs分别表示最大前缀和,最大后缀和,最大子段和。具体的更新函数可以参照线段树。特别要注意标记的下推,更新标记时要考虑全面。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF -1e9
#define maxn 500006
using namespace std;
struct node{
node* ch[2];
int key,num,sum,maxs,maxl,maxr,tag,flip;
void add_tag(int k){
key=tag=k;sum=k*num;
if(k>0)maxs=maxl=maxr=k*num;
else maxs=maxl=maxr=k;
}
void add_flip(){
swap(maxl,maxr);swap(ch[0],ch[1]);flip^=1;
}
void pushdown(){
if(tag!=INF)ch[0]->add_tag(tag),ch[1]->add_tag(tag),tag=INF;
if(flip)ch[0]->add_flip(),ch[1]->add_flip(),flip=0;
}
int maintain(){
sum=ch[0]->sum+key+ch[1]->sum;num=ch[0]->num+1+ch[1]->num;
maxl=max(max(ch[0]->maxl,ch[0]->sum+key),ch[0]->sum+key+ch[1]->maxl);
maxr=max(max(ch[1]->maxr,ch[1]->sum+key),ch[1]->sum+key+ch[0]->maxr);
maxs=max(key,max(ch[0]->maxr+key+ch[1]->maxl,max(max(ch[0]->maxs,ch[1]->maxs),max(ch[0]->maxr+key,key+ch[1]->maxl))));
}
int cmp(int &k){
if(k<ch[0]->num+1)return 0;
if(k==ch[0]->num+1)return -1;
k-=ch[0]->num+1;return 1;
}
}nul;
typedef node* pnode;
pnode rt,null=&nul;
pnode newnode(int key){
pnode p=new node;p->key=p->sum=p->maxs=p->maxl=p->maxr=key;p->ch[0]=p->ch[1]=null;
p->tag=INF;p->flip=0;p->num=1;
return p;
}
void rot(pnode &p,int d){
pnode k=p->ch[d^1];p->ch[d^1]=k->ch[d];k->ch[d]=p;
p->maintain();k->maintain();p=k;
}
void splay(pnode &p,int k){
p->pushdown();
int d1=p->cmp(k);
if(d1!=-1){
p->ch[d1]->pushdown();int d2=p->ch[d1]->cmp(k);
if(d2!=-1){
splay(p->ch[d1]->ch[d2],k);
if(d1==d2)rot(p,d1^1);
else rot(p->ch[d1],d2^1);
}
rot(p,d1^1);
}
}
void del(pnode p){
if(p==null)return;
del(p->ch[0]);del(p->ch[1]);
delete p;
}
pnode build(int l,int r,int*arr){
if(l>r)return null;
int mid=(l+r)/2;
pnode p=newnode(*(arr+mid));
p->ch[0]=build(l,mid-1,arr);p->ch[1]=build(mid+1,r,arr);
p->maintain();
return p;
}
void print_splay(pnode p){
if(p==null)return;
p->pushdown();
print_splay(p->ch[0]);
// printf("%d ",p->key);
print_splay(p->ch[1]);
}
int _read(){
char ch=getchar();int p,sum=0;
while((ch!='-')&&(!(ch>='0'&&ch<='9')))ch=getchar();
if(ch=='-')p=-1,ch=getchar();else p=1;
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=getchar();
return sum*p;
}
int n,m,c[maxn];
int main(){
null->ch[0]=null->ch[1]=null;null->num=null->flip=null->sum=null->key=0;null->tag=null->maxl=null->maxr=null->maxs=INF;
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
n=_read();m=_read();
for(int i=1;i<=n;i++)c[i]=_read();c[n+1]=0;
rt=build(0,n+1,c);
for(int t=1;t<=m;t++){
char s[30];scanf("%s",s);
if(s[0]=='I'){
int x=_read(),tot=_read();x++;
for(int i=1;i<=tot;i++)c[i]=_read();
splay(rt,x);splay(rt->ch[1],1);
rt->ch[1]->ch[0]=build(1,tot,c);
rt->ch[1]->maintain();rt->maintain();
}else
if(s[0]=='D'){
int x=_read(),tot=_read();x++;
splay(rt,x-1);splay(rt->ch[1],tot+1);
del(rt->ch[1]->ch[0]);rt->ch[1]->ch[0]=null;
rt->ch[1]->maintain();rt->maintain();
}else
if(s[2]=='K'){
int x=_read(),tot=_read(),y=_read();x++;
splay(rt,x-1);splay(rt->ch[1],tot+1);
rt->ch[1]->ch[0]->add_tag(y);
}else
if(s[0]=='R'){
int x=_read(),tot=_read();x++;
splay(rt,x-1);splay(rt->ch[1],tot+1);
rt->ch[1]->ch[0]->add_flip();
}else
if(s[0]=='G'){
int x=_read(),tot=_read();x++;
splay(rt,x-1);splay(rt->ch[1],tot+1);
printf("%d\n",rt->ch[1]->ch[0]->sum);
}else{
splay(rt,1);splay(rt->ch[1],rt->ch[1]->num);
printf("%d\n",rt->ch[1]->ch[0]->maxs);
}
// print_splay(rt);
}
return 0;
}