题目大意:维护一个数列,支持一堆操作(懒得写了)
题解:上fhq treap……
我的收获:2333
#include <cstdio>
#include <queue>
#include <cstdlib>
using namespace std;
#define N 500010
#define INF 0x3f3f3f3f
int n,m,root,cnt;
int ch[N][2],siz[N];
int k[N],tar[N],sum[N];
int lmx[N],rmx[N],tmx[N];
int cov[N];
bool rev[N];
int flag;
queue<int> trash;
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;
}
inline int max(int x,int y){return x>y?x:y;}
inline void swap(int &x,int &y){x^=y^=x^=y;}
/*
inline int newnode(int v)
{
int x;
if(!trash.empty()) x=trash.front(),trash.pop();
else x=++cnt;
cov[x]=INF,tar[x]=rand(),siz[x]=1;
k[x]=sum[x]=tmx[x]=v;
lmx[x]=rmx[x]=max(v,0);
return x;
}
*/
int newnode(int v)
{
int x;
if (!trash.empty())
x=trash.front(),trash.pop();
else
x=++cnt;
ch[x][0]=ch[x][1]=rev[x]=0;
cov[x]=INF,tar[x]=rand(),siz[x]=1;
k[x]=sum[x]=tmx[x]=v;
lmx[x]=rmx[x]=max(v,0);
return x;
}
inline void rever(int x)
{
swap(ch[x][0],ch[x][1]);
swap(lmx[x],rmx[x]);
rev[x]^=1;
}
inline void cover(int x,int v)
{
k[x]=v,sum[x]=siz[x]*v;
lmx[x]=rmx[x]=max(sum[x],0);
tmx[x]=max(sum[x],k[x]);
cov[x]=v;
}
/*
inline void update(int x)
{
int l=ch[x][0],r=ch[x][1];
siz[x]=siz[l]+siz[r]+1;
sum[x]=sum[l]+sum[r]+k[x];
tmx[x]=max(tmx[l],tmx[r]);
tmx[x]=max(tmx[x],rmx[l]+k[x]+lmx[r]);
lmx[x]=max(lmx[l],lmx[r]+k[x]+sum[l]);
rmx[x]=max(rmx[r],rmx[l]+k[x]+sum[r]);
}
*/
void update(int x)
{
if (ch[x][0] && ch[x][1])
{
siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+k[x];
tmx[x]=max(tmx[ch[x][0]],tmx[ch[x][1]]);
tmx[x]=max(tmx[x],rmx[ch[x][0]]+k[x]+lmx[ch[x][1]]);
lmx[x]=max(lmx[ch[x][0]],sum[ch[x][0]]+k[x]+lmx[ch[x][1]]);
rmx[x]=max(rmx[ch[x][1]],sum[ch[x][1]]+k[x]+rmx[ch[x][0]]);
}
else
if (ch[x][0])
{
siz[x]=siz[ch[x][0]]+1;
sum[x]=sum[ch[x][0]]+k[x];
tmx[x]=max(tmx[ch[x][0]],rmx[ch[x][0]]+k[x]);
lmx[x]=max(lmx[ch[x][0]],sum[ch[x][0]]+k[x]);
lmx[x]=max(0,lmx[x]);
rmx[x]=max(0,k[x]+rmx[ch[x][0]]);
}
else
if (ch[x][1])
{
siz[x]=siz[ch[x][1]]+1;
sum[x]=sum[ch[x][1]]+k[x];
tmx[x]=max(tmx[ch[x][1]],lmx[ch[x][1]]+k[x]);
rmx[x]=max(rmx[ch[x][1]],sum[ch[x][1]]+k[x]);
rmx[x]=max(0,rmx[x]);
lmx[x]=max(0,lmx[ch[x][1]]+k[x]);
}
else
{
siz[x]=1,sum[x]=tmx[x]=k[x];
lmx[x]=rmx[x]=max(k[x],0);
}
}
inline void pushdown(int x)
{
if(rev[x])
{
if(ch[x][0]) rever(ch[x][0]);
if(ch[x][1]) rever(ch[x][1]);
}
if(cov[x]!=INF)
{
if(ch[x][0]) cover(ch[x][0],cov[x]);
if(ch[x][1]) cover(ch[x][1],cov[x]);
}
rev[x]=0;cov[x]=INF;
}
void split(int now,int w,int &x,int &y)
{
if(!now) x=y=0;
else
{
pushdown(now);
if (siz[ch[now][0]]>=w)
y=now,split(ch[now][0],w,x,ch[now][0]);
else
x=now,split(ch[now][1],w-siz[ch[now][0]]-1,ch[now][1],y);
update(now);
}
}
int merge(int x,int y)
{
if(x) pushdown(x);
if(y) pushdown(y);
if(x*y==0) return x+y;
if(tar[x]<tar[y])
{
ch[x][1]=merge(ch[x][1],y);
update(x);return x;
}
else
{
ch[y][0]=merge(x,ch[y][0]);
update(y);return y;
}
}
void trashcol(int x)
{
if(!x) return;
trash.push(x);
trashcol(ch[x][0]);
trashcol(ch[x][1]);
}
/*
inline void insert()
{
printf("%d\n",siz[1]);
int pos=read(),len=read(),x,y;
int rt=0;
for(int i=1;i<=len;i++) rt=merge(rt,newnode(read()));
split(root,pos,x,y);
root=merge(merge(x,rt),y);
printf("%d\n",siz[1]);
}
*/
int build(int *data,int n)
{
int x,last=0;static int sta[N],top;
for(int i=1;i<=n;i++)
{
x=newnode(data[i]),last=0;
while(top && tar[sta[top]]>tar[x])
update(sta[top]),last=sta[top],
sta[top--]=0;
if (top)
ch[sta[top]][1]=x;
ch[x][0]=last,sta[++top]=x;
}
while(top)
update(sta[top--]);
return sta[1];
}
void insert()
{
int pos=read(),len=read(),x,y;
static int datas[N];
for (int i=1;i<=len;i++)
datas[i]=read();
int rt=build(datas,len);
split(root,pos,x,y);
root=merge(merge(x,rt),y);
}
inline void delets()
{
int pos=read(),len=read(),x1,x2,y1,y2;
split(root,pos-1,x1,x2);
split(x2,len,y1,y2);
root=merge(x1,y2);
trashcol(y1);
}
inline void covers()
{
int pos=read(),len=read(),v=read(),x1,x2,y1,y2;
split(root,pos-1,x1,x2);
split(x2,len,y1,y2);
cover(y1,v);
root=merge(x1,merge(y1,y2));
}
inline void reverses()
{
int pos=read(),len=read(),x1,x2,y1,y2;
split(root,pos-1,x1,x2);
split(x2,len,y1,y2);
rever(y1);
root=merge(x1,merge(y1,y2));
}
inline void sums()
{
int pos=read(),len=read(),x1,x2,y1,y2;
split(root,pos-1,x1,x2);
split(x2,len,y1,y2);
printf("%d\n",sum[y1]);
root=merge(x1,merge(y1,y2));
}
inline void maxs(){printf("%d\n",tmx[root]);}
void work()
{
char opt[22];
while(m--)
{
scanf("%s",opt);
switch (opt[0])
{
case 'I':insert();break;
case 'D':delets();break;
case 'M':{
if(opt[2]=='K') covers();
else maxs();
break;
}
case 'R':reverses();break;
case 'G':sums();break;
}
}
}
void init()
{
srand(513);
n=read(),m=read();static int a[N];
for (int i=1;i<=n;i++)
a[i]=read();
root=build(a,n);
//for(int i=1;i<=n;i++) root=i==1?newnode(read()):merge(root,newnode(read()));
}
int main()
{
init();
work();
return 0;
}