用的FHQ-Treap
只A了第一个点,后面全RE,数据下下来发现运行到一个普通的insert操作(只插入了4000个数左右)的时候程序就停止运行了,输出tot大小发现达到了4e5,但对比题解程序发现4e5是正常的。
都调了好几天了,各位大佬救救吧!
#include<bits/stdc++.h>
#define inf INT_MAX
using namespace std;
const int MAXN=5e5+5;
int n,m,tot,root;
struct node{
int val,sz,sum,rand,mx,mxl,mxr,tagr,tagc;
}t[MAXN];
int ls[MAXN],rs[MAXN];
stack<int>rec;
#define lc ls[u]
#define rc rs[u]
void pushup(int u)
{
t[u].sz=t[lc].sz+t[rc].sz+1;
t[u].sum=t[lc].sum+t[rc].sum+t[u].val;
t[u].mx=max(max(t[lc].mxr+t[rc].mxl,0)+t[u].val,max(t[lc].mx,t[rc].mx));
t[u].mxl=max(max(t[lc].mxl,t[lc].sum+t[rc].mxl+t[u].val),0);
t[u].mxr=max(0,max(t[rc].mxr,t[rc].sum+t[lc].mxr+t[u].val));
}
int newnode(int val)
{
if(!rec.empty())
{
int u=rec.top();
rec.pop();
t[u]=(node){val,1,val,rand(),val,max(0,val),max(0,val),0,inf};
return u;
}
t[++tot]=(node){val,1,val,rand(),val,max(0,val),max(0,val),0,inf};
return tot;
}
void tr(int u)
{
swap(lc,rc);
swap(t[u].mxl,t[u].mxr);
t[u].tagr^=1;
}
void tc(int u,int c)
{
t[u].val=c;
t[u].sum=t[u].sz*c;
t[u].mx=max(c,t[u].sum);//此题中,区间最大子段不能为空
t[u].mxl=t[u].mxr=max(0,t[u].sum);//这里可以取空是因为 pushup 的时候会加上 t[u].val
t[u].tagc=c;
}
void pushdown(int u)
{
if(t[u].tagr)
{
if(lc) tr(lc);
if(rc) tr(rc);
t[u].tagr=0;
}
if(t[u].tagc!=inf)
{
if(lc) tc(lc,t[u].tagc);
if(rc) tc(rc,t[u].tagc);
t[u].tagc=inf;
}
}
void split(int u,int pos,int &x,int &y)
{
if(!u)
{
x=y=0;
return;
}
pushdown(u);
if(pos<=t[lc].sz) y=u,split(lc,pos,x,lc);
else x=u,split(rc,pos-t[lc].sz-1,rc,y);
pushup(u);
}
int merge(int x,int y)
{
if(!x||!y) return x|y;
if(t[x].rand<t[y].rand)
{
pushdown(x);
rs[x]=merge(rs[x],y);
pushup(x);
return x;
}
else
{
pushdown(y);
ls[y]=merge(x,ls[y]);
pushup(y);
return y;
}
}
int data[MAXN];
void ins(int pos,int len)
{
int newr=0;
for(int i=1;i<=len;i++) newr=merge(newr,newnode(data[i]));
int x,y;
split(root,pos,x,y);
root=merge(merge(x,newr),y);
}
void remove(int u)
{
if(!u) return;
rec.push(u);
remove(lc);
remove(rc);
}
void del(int pos,int len)
{
int x,y,yx,yy;
split(root,pos-1,x,y);
split(y,len,yx,yy);
remove(yx);
root=merge(x,yy);
}
void cover(int pos,int len,int c)
{
int x,y,yx,yy;
split(root,pos-1,x,y);
split(y,len,yx,yy);
tc(yx,c);
root=merge(x,merge(yx,yy));
}
void rev(int pos,int len)
{
int x,y,yx,yy;
split(root,pos-1,x,y);
split(y,len,yx,yy);
tr(yx);
root=merge(x,merge(yx,yy));
}
void qsum(int pos,int len)
{
int x,y,yx,yy;
split(root,pos-1,x,y);
split(y,len,yx,yy);
printf("%d\n",t[yx].sum);
root=merge(x,merge(yx,yy));
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&data[i]);
ins(0,n);
while(m--)
{
string op;
cin>>op;
if(op=="INSERT")
{
int pos,len;
scanf("%d%d",&pos,&len);
for(int i=1;i<=len;i++) scanf("%d",&data[i]);
ins(pos,len);
}
if(op=="DELETE")
{
int pos,len;
scanf("%d%d",&pos,&len);
del(pos,len);
}
if(op=="MAKE-SAME")
{
int pos,len,c;
scanf("%d%d%d",&pos,&len,&c);
cover(pos,len,c);
}
if(op=="REVERSE")
{
int pos,len;
scanf("%d%d",&pos,&len);
rev(pos,len);
}
if(op=="GET-SUM")
{
int pos,len;
scanf("%d%d",&pos,&len);
qsum(pos,len);
}
if(op=="MAX-SUM") printf("%d\n",t[root].mx);
}
return 0;
}