题目描述:http://www.lydsy.com/JudgeOnline/problem.php?id=1500
题解:
splay模板。
但是好难打啊QWQ
哭着求llgyc大神给了份模板开始抄。还要提高自己的数据结构水平啊。
参考代码:
#include<set>
#include<map>
#include<queue>
#include<cmath>
#include<string>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,a,b) for (int i=a; i<=b; i++)
#define per(i,a,b) for (int i=a; i>=b; i--)
using namespace std;
typedef long long LL;
inline int read() {
int x=0,f=1; char ch=getchar();
while (!(ch>='0'&&ch<='9')) {if (ch=='-')f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') {x=x*10+(ch-'0'); ch=getchar();}
return x*f;
}
const int N = 500005;
const int INF = 100000000;
int n,m,cnt=0,root;
int a[N];
int lc[N],rc[N],val[N],fa[N],size[N],lmax[N],rmax[N],mx[N],sum[N],rev[N],tag[N];
int head=1,tail=0,q[N];
inline void init() {rep(i,1,N-1) q[i]=i;}
inline int newn() {int ret=q[head]; head=(head+1)%N;lc[ret]=rc[ret]=rev[ret]=lmax[ret]=rmax[ret]=mx[ret]=0;return ret;}
inline void release(int x) {q[tail]=x; tail=(tail+1)%N;}
inline void del(int x) {if (!x) return; release(x); del(lc[x]); del(rc[x]);}
inline void pushdown(int x) {
if (rev[x]) {
rev[x]^=1; rev[lc[x]]^=1; rev[rc[x]]^=1;
swap(lc[x],rc[x]); swap(lmax[x],rmax[x]);
}
if (tag[x]!=-INF) {
tag[lc[x]]=tag[x]; tag[rc[x]]=tag[x];
val[x]=tag[x]; sum[x]=tag[x]*size[x];
lmax[x]=rmax[x]=mx[x]=max(tag[x],tag[x]*size[x]);
tag[x]=-INF;
}
}
inline void pushup(int x) {
size[x]=size[lc[x]]+size[rc[x]]+1;
sum[x]=sum[lc[x]]+sum[rc[x]]+val[x];
lmax[x]=max(lmax[lc[x]],sum[lc[x]]+val[x]+max(lmax[rc[x]],0));
rmax[x]=max(rmax[rc[x]],sum[rc[x]]+val[x]+max(rmax[lc[x]],0));
mx[x]=max(val[x]+max(max(rmax[lc[x]],lmax[rc[x]]),max(0,lmax[rc[x]]+rmax[lc[x]])),max(mx[lc[x]],mx[rc[x]]));
}
inline int build(int x,int l,int r) {
if (l>r) return 0;
if (l==r) {
cnt=newn(); val[cnt]=a[l]; fa[cnt]=x; tag[cnt]=-INF;
pushup(cnt); return cnt;
}
int mid=(l+r)>>1;
int ret=newn(); val[ret]=a[mid]; fa[ret]=x; tag[ret]=-INF;
lc[ret]=build(ret,l,mid-1); rc[ret]=build(ret,mid+1,r);
pushup(ret); return ret;
}
inline void rotate(int x) {
int y=fa[x],z=fa[y],b;
if (x==lc[y]) b=rc[x]; else b=lc[x];
fa[x]=z; fa[y]=x; if (b) fa[b]=y;
if (z) {if (lc[z]==y) lc[z]=x; else rc[z]=x;}
if (x==lc[y]) rc[x]=y,lc[y]=b; else lc[x]=y,rc[y]=b;
pushup(y); pushup(x);
}
int stk[N];
inline void splay(int x,int goal=0) {
int top=0; stk[++top]=x; for (int i=x;i!=root;i=fa[i]) stk[++top]=fa[i];
while (top) pushdown(stk[top--]);
while (fa[x]!=goal) {
int y=fa[x],z=fa[y];
if (z!=goal) {
if ((lc[z]==y)^(lc[y]==x)) rotate(x);
else rotate(y);
}
rotate(x);
}
if (!goal) root=x;
}
inline int find(int k) {
int x=root;
while (1) {
if (lc[x]) pushdown(lc[x]);
if (rc[x]) pushdown(rc[x]);
if (size[lc[x]]+1==k) return x;
if (size[lc[x]]>=k) x=lc[x];else k-=(size[lc[x]]+1),x=rc[x];
}
}
inline void Insert(int pos,int num){
rep(i,1,num) a[i]=read();
int k1=find(pos+1),k2=find(pos+2);
splay(k1);splay(k2,k1);
lc[k2]=build(k2,1,num);
pushup(k2);pushup(k1);
}
inline void Delete(int pos,int num){
int k1=find(pos),k2=find(pos+num+1);
splay(k1);splay(k2,k1);del(lc[k2]);
lc[k2]=0;pushup(k2);pushup(k1);
}
inline void Modify(int pos,int num,int c){
int k1=find(pos),k2=find(pos+num+1);
splay(k1);splay(k2,k1);
tag[lc[k2]]=c;pushdown(lc[k2]);
pushup(k2);pushup(k1);
}
inline void Reverse(int pos,int num){
int k1=find(pos),k2=find(pos+num+1);
splay(k1);splay(k2,k1);
rev[lc[k2]]^=1;pushdown(lc[k2]);
pushup(k2);pushup(k1);
}
inline void getSum(int pos,int num){
if(!num){printf("0\n");return;}
int k1=find(pos),k2=find(pos+num+1);
splay(k1);splay(k2,k1);
pushdown(lc[k2]);pushup(k2);pushup(k1);
printf("%d\n",sum[lc[k2]]);
}
int main() {
init(); n=read(),m=read(); rep(i,1,n) a[i]=read(); a[0]=a[n+1]=-INF;
lmax[0]=rmax[0]=mx[0]=tag[0]=-INF; root=build(0,0,n+1);
char opt[20];
while (m--) {
scanf("%s",opt); int pos,num,c;
switch(opt[0]){
case 'I':scanf("%d%d",&pos,&num);Insert(pos,num);break;
case 'D':scanf("%d%d",&pos,&num);Delete(pos,num);break;
case 'R':scanf("%d%d",&pos,&num);Reverse(pos,num);break;
case 'G':scanf("%d%d",&pos,&num);getSum(pos,num);break;
case 'M':if(o pt[2]=='K') {scanf("%d%d%d",&pos,&num,&c);Modify(pos,num,c);}else printf("%d\n",mx[root]);
}
}
return 0;
}