终于打败大boss了,耗时一下午。
应该是splay维护序列题型的巅峰了吧。
这道题不能单纯的开点,因为会MLE,所以要用回收节点的过程。
说一下搞法吧:
1、插入,提取区间,递归建树
2、删除,提取区间,把删去的点用一个栈储存下来
3、修改,提取区间,打个标记
4、翻转,提取区间,打个标记
5、求和、最大连续子段和,维护一下就可以了。
WA点:
这道题不用开longlong,简直是福利
没说数据范围,需要回收内存
标记稍微处理一下就可以了没什么
初始化节点注意把权值赋成-inf,虽然好像没用什么用
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<iostream>
#define inf 1010000000
#define maxn 510010
using namespace std;
int fa[maxn],ch[maxn][2],w[maxn],size[maxn],sum[maxn],lmax[maxn],rmax[maxn],ans[maxn];
bool rev[maxn];
bool tag[maxn];
int a[maxn];
int st[maxn];
char s[20];
int n,m,T,tot,root,top;
int newnode()
{
int num;
if (top) num=st[top--]; else num=++tot;
ch[num][0]=ch[num][1]=fa[num]=0;
tag[num]=rev[num]=0;
size[num]=1;
sum[num]=w[num]=rmax[num]=lmax[num]=-inf;
return num;
}
void update(int x)
{
if (!x) return;
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+w[x];
lmax[x]=max(lmax[ch[x][0]],sum[ch[x][0]]+w[x]+max(0,lmax[ch[x][1]]));
rmax[x]=max(rmax[ch[x][1]],sum[ch[x][1]]+w[x]+max(0,rmax[ch[x][0]]));
ans[x]=max(max(ans[ch[x][0]],ans[ch[x][1]]),max(0,rmax[ch[x][0]])+w[x]+max(0,lmax[ch[x][1]]));
}
void reverse(int x)
{
if (!x) return;
swap(lmax[x],rmax[x]);
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void replace(int x,int d)
{
if (!x) return;
w[x]=d;sum[x]=d*size[x];
lmax[x]=rmax[x]=ans[x]=max(d,d*size[x]);
tag[x]=1;rev[x]=0;
}
void push_down(int x)
{
if (rev[x])
{
if (ch[x][0]) reverse(ch[x][0]);
if (ch[x][1]) reverse(ch[x][1]);
rev[x]=0;
}
if (tag[x])
{
if (ch[x][0]) replace(ch[x][0],w[x]);
if (ch[x][1]) replace(ch[x][1],w[x]);
tag[x]=0;
}
}
int dir(int x)
{
return x==ch[fa[x]][1];
}
void rotate(int x)
{
int y,z,a,b,c;
y=fa[x];z=fa[y];b=dir(x);a=ch[x][!b];
if (z==0) root=x;
else
{
c=dir(y);ch[z][c]=x;
}
fa[x]=z;fa[y]=x;ch[x][!b]=y;ch[y][b]=a;
if (a) fa[a]=y;
update(y);update(x);
}
void down(int x)
{
if (fa[x]) down(fa[x]);
push_down(x);
}
void splay(int x,int i)
{
down(x);
int y,z,b,c;
while (fa[x]!=i)
{
y=fa[x];z=fa[y];
if (z==i) rotate(x);
else
{
b=dir(x);c=dir(y);
if (b^c)
{
rotate(x);rotate(x);
}
else
{
rotate(y);rotate(x);
}
}
}
}
int find_k(int x,int k)
{
push_down(x);
if (size[ch[x][0]]==k-1) return x;
if (size[ch[x][0]]>k-1) return find_k(ch[x][0],k);
else return find_k(ch[x][1],k-size[ch[x][0]]-1);
}
void build_tree(int l,int r,int tt)
{
int mid=(l+r)/2;
w[tt]=a[mid];
if (l==r) {sum[tt]=lmax[tt]=rmax[tt]=ans[tt]=w[tt];size[tt]=1;return;}
if (l<mid) {ch[tt][0]=newnode();fa[ch[tt][0]]=tt;build_tree(l,mid-1,ch[tt][0]);}
if (mid<r) {ch[tt][1]=newnode();fa[ch[tt][1]]=tt;build_tree(mid+1,r,ch[tt][1]);}
update(tt);
}
int Query(int l,int num)
{
int x=find_k(root,l);splay(x,0);
int y=find_k(ch[x][1],num+1);splay(y,x);
return sum[ch[y][0]];
}
void Insert(int l,int num)
{
for (int i=1;i<=num;i++) scanf("%d",&a[i]);
int x=find_k(root,l+1);splay(x,0);
int y=find_k(ch[x][1],1);splay(y,x);
ch[y][0]=newnode();fa[ch[y][0]]=y;
build_tree(1,num,ch[y][0]);
update(y);update(x);
}
void erase(int x)
{
if (!x) return;
st[++top]=x;
if (ch[x][0]) erase(ch[x][0]);
if (ch[x][1]) erase(ch[x][1]);
}
void Delete(int l,int num)
{
int x=find_k(root,l);splay(x,0);
int y=find_k(ch[x][1],num+1);splay(y,x);
erase(ch[y][0]);
fa[ch[y][0]]=0;ch[y][0]=0;
update(y);update(x);
}
void Reverse(int l,int num)
{
int x=find_k(root,l);splay(x,0);
int y=find_k(ch[x][1],num+1);splay(y,x);
reverse(ch[y][0]);
update(y);update(x);
}
void Replace(int l,int num,int d)
{
int x=find_k(root,l);splay(x,0);
int y=find_k(ch[x][1],num+1);splay(y,x);
replace(ch[y][0],d);
update(y);update(x);
}
int main()
{
lmax[0]=rmax[0]=ans[0]=-inf;
tot=2;root=1;
fa[1]=0;size[1]=2;ch[1][1]=2;w[1]=sum[1]=lmax[1]=rmax[1]=-inf;
fa[2]=1;size[2]=1;w[2]=sum[2]=lmax[2]=rmax[2]=-inf;
scanf("%d%d",&n,&T);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
ch[2][0]=newnode();fa[ch[2][0]]=2;
build_tree(1,n,ch[2][0]);
update(2);update(1);
while (T--)
{
int x,y,z;
scanf("%s",s);
if (s[2]=='X') printf("%d\n",ans[root]);
if (s[0]=='G')
{
scanf("%d%d",&x,&y);
printf("%d\n",Query(x,y));
}
if (s[0]=='I')
{
scanf("%d%d",&x,&y);
Insert(x,y);
}
if (s[0]=='D')
{
scanf("%d%d",&x,&y);
Delete(x,y);
}
if (s[0]=='R')
{
scanf("%d%d",&x,&y);
Reverse(x,y);
}
if (s[4]=='-')
{
scanf("%d%d%d",&x,&y,&z);
Replace(x,y,z);
}
}
return 0;
}