我這個題22次失敗送出(WA & TLE & MLE & RE),然後才AC了。。。
這個題真的把Splay當成了線段樹來用,打了好多标記,還一直pushup&&pushdown
其實所有操作都差不多,隻是打的标記不同罷了。
比如我們要操作[L,R],那麼就将L-1 Splay到根,将R+1 Splay到根的右兒子,這樣就可以操作了(自己腦補一下)
然後這個題有一個坑點,就是最大子段和必須選,也就是說,如果全是負數,還是必須選一個,不能輸出零。
其實這個題就是操作太多,才不好調,每個操作單獨拉出來都不難。
代碼:(跑得還挺快 https://www.luogu.org/record/show?rid=4147310)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#define ll long long
using namespace std;
inline int read(){
int x=;char ch=' ';int f=;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')f=-,ch=getchar();
while(ch>='0'&&ch<='9')x=(x<<)+(x<<)+(ch^),ch=getchar();
return x*f;
}
const int N=+;
const int inf=+;
int n,m,sz,root;
int key[N],ch[N][],sum[N],mx[N],lx[N],rx[N],rev[N],cg[N],size[N],f[N];
int s[N],top;
inline int New(){return top?s[top--]:++sz;}
inline void pre(int x,int v){
ch[x][]=ch[x][]=f[x]=cg[x]=rev[x]=;
size[x]=;key[x]=sum[x]=mx[x]=lx[x]=rx[x]=v;
}
inline void cover(int x,int v){
cg[x]=;sum[x]=v*size[x];
key[x]=v;mx[x]=lx[x]=rx[x]=max(key[x],sum[x]);
rev[x]=;
}
inline void rever(int x){
if(cg[x])return;
rev[x]^=;
swap(ch[x][],ch[x][]);swap(lx[x],rx[x]);
}
inline void update(int x){
int l=ch[x][],r=ch[x][];
sum[x]=sum[l]+sum[r]+key[x];
lx[x]=max(lx[l],sum[l]+key[x]+max(lx[r],));
rx[x]=max(rx[r],sum[r]+key[x]+max(rx[l],));
mx[x]=max(max(mx[l],mx[r]),max(,lx[r])+max(,rx[l])+key[x]);
size[x]=size[l]+size[r]+;
}
inline void pushdown(int x){
int l=ch[x][],r=ch[x][];
if(rev[x]){
if(l)rever(l);
if(r)rever(r);
rev[x]=;
}
if(cg[x]){
if(l)cover(l,key[x]);
if(r)cover(r,key[x]);
cg[x]=;
}
}
inline bool get(int x){return ch[f[x]][]==x;}
inline void clear(int x){ch[x][]=ch[x][]=f[x]=size[x]=sum[x]=key[x]=lx[x]=rx[x]=mx[x]=rev[x]=cg[x]=;}
inline void rotate(int x){
int y=f[x],z=f[y],w=get(x),w2=get(y);
ch[y][w]=ch[x][w^];f[ch[y][w]]=y;
ch[x][w^]=y;f[y]=x;
f[x]=z;if(z)ch[z][w2]=x;
update(y);update(x);
}
inline void splay(int x,int goal){
for(int fa=;(fa=f[x])!=goal;rotate(x))
if(f[fa]!=goal)
rotate((get(x)==get(fa))?fa:x);
if(!goal)root=x;
}
inline int kth(int k){
int now=root;
while(){
pushdown(now);
if(k<=size[ch[now][]])now=ch[now][];
else{
if(k<=size[ch[now][]]+){return now;}
k-=size[ch[now][]]+;now=ch[now][];
}
}
}
int v[N];
inline void build(int &x,int l,int r,int fa){
if(l>r){x=;return;}
int mid=(l+r)>>;
x=New();pre(x,v[mid]);f[x]=fa;
if(l==r)return;
build(ch[x][],l,mid-,x);
build(ch[x][],mid+,r,x);
update(x);
}
inline void insert(){
int x=read();int tot=read();if(!tot)return;
for(int i=;i<=tot;i++)v[i]=read();
int l=kth(x+);splay(l,);
int r=kth(x+);splay(r,l);
build(ch[r][],,tot,r);
update(r);update(l);
}
inline void recycle(int x){
if(!x)return;
s[++top]=x;
recycle(ch[x][]);recycle(ch[x][]);
}
inline void del(){
int x=read();int tot=read();if(!tot)return;
int l=kth(x);splay(l,);
int r=kth(x+tot+);splay(r,l);
recycle(ch[r][]);ch[r][]=;
update(r);update(l);
}
inline void modify(){
int x=read();int tot=read();int c=read();if(!tot)return;
int l=kth(x);splay(l,);
int r=kth(x+tot+);splay(r,l);
cover(ch[r][],c);
update(r);update(l);
}
inline void reverse(){
int x=read();int tot=read();if(!tot)return;
int l=kth(x);splay(l,);
int r=kth(x+tot+);splay(r,l);
rever(ch[r][]);
update(r);update(l);
}
inline void query_sum(){
int x=read();int tot=read();if(!tot){printf("0\n");return;}
int l=kth(x);splay(l,);
int r=kth(x+tot+);splay(r,l);
printf("%d\n",sum[ch[r][]]);
}
inline void query_mx(){
printf("%d\n",mx[root]);
}
inline void print(int x){
if(ch[x][])print(ch[x][]);
cout<<"data of "<<x<<":"<<endl;
cout<<"key["<<x<<"]="<<key[x]<<' ';
cout<<"size["<<x<<"]="<<size[x]<<endl;
cout<<"ls["<<x<<"]="<<ch[x][]<<' ';
cout<<"rs["<<x<<"]="<<ch[x][]<<' ';
cout<<"sum["<<x<<"]="<<sum[x]<<endl;
cout<<"lx["<<x<<"]="<<lx[x]<<' ';
cout<<"rx["<<x<<"]="<<rx[x]<<' ';
cout<<"mx["<<x<<"]="<<mx[x]<<endl;
cout<<"fa["<<x<<"]="<<f[x]<<' ';
cout<<"cg["<<x<<"]="<<cg[x]<<' ';
cout<<"rev["<<x<<"]="<<rev[x]<<endl;
cout<<"end data."<<endl;
cout<<endl;
if(ch[x][])print(ch[x][]);
}
int main(){
// freopen("test.out","w",stdout);
n=read();m=read();
mx[]=v[]=v[n+]=-inf;
// mx[0]=-inf;
for(int i=;i<=n+;i++)v[i]=read();
build(root,,n+,);
// int _1=kth(1);int _n=kth(n+2);
// mx[_1]=-inf;mx[_n]=-inf;
char ch[];
while(m--){
scanf("%s",ch);
// printf("%s\n",ch);
if(ch[]=='S')insert();
else if(ch[]=='L')del();
else if(ch[]=='K')modify();
else if(ch[]=='V')reverse();
else if(ch[]=='T')query_sum();
else query_mx();
// print(root);
// cout<<endl<<endl<<endl<<endl<<endl;
}
return ;
}