这题太TM不容易了 反复对拍调试了一下午+一晚上终于调出来了、、
看起来很简单,但实际上坑、细节相当的多:
这题需要维护 正常的区间加、赋值操作之外,还需要维护历史最大连加、历史最大赋值
所以pushdown异常恶心:
但因为上面的节点一定比下面的节点晚,所以可以用向下合并法 把上面的标记放到下面标记的后面考虑:
而且很重要的是要分类讨论、、不要怕麻烦
pushdown时按照上图来就行了
但注意if和直接复制时出的错
犯的错误:1、没有分类讨论的习惯,老想一个代码完事(懒)
2、复制时<<忘了变成<<|
3、max2忘了赋初值
4、忘了+时赋值的合并
码:
#include<iostream>
#include<cstdio>
using namespace std;
#define zuo l,mid,o<<1
#define you mid+1,r,o<<1|1
#define N 100004
int max1[N<<2],max2[N<<2],jia[N<<2],fuzhi[N<<2],a,b,c,n,q,m,op,ans,i,mj[N<<2],mf[N<<2];
char ch;
void up(int o)
{
max1[o]=max(max1[o<<1],max1[o<<1|1]); max2[o]=max(max2[o],max1[o]);
}
void jian(int l,int r,int o)
{ fuzhi[o]=-999999999; mf[o]=-999999999; max2[o]=-999999999;
if(l==r)
{
scanf("%d",&max1[o]); max2[o]=max1[o];
return;
}
int mid=(l+r)>>1;
jian(zuo);
jian(you);
up(o);
}
void down(int o)
{
// 合并法
max2[o<<1]=max(max2[o<<1],max1[o<<1]+mj[o]);max2[o<<1|1]=max(max2[o<<1|1],mf[o]);
max2[o<<1|1]=max(max2[o<<1|1],max1[o<<1|1]+mj[o]);max2[o<<1]=max(max2[o<<1],mf[o]);
if(mf[o<<1]!=-999999999)
{
//mj[o<<1]=max(jia[o<<1]+mj[o],mj[o<<1]);
mf[o<<1]=max(mf[o<<1],max(mf[o],max1[o<<1]+mj[o]));
} else if(mf[o<<1]==-999999999)
{
mj[o<<1]=max(jia[o<<1]+mj[o],mj[o<<1]);
mf[o<<1]=mf[o];
}
if(mf[o<<1|1]!=-999999999)
{
//mj[o<<1]=max(jia[o<<1]+mj[o],mj[o<<1]);
mf[o<<1|1]=max(mf[o<<1|1],max(mf[o],max1[o<<1|1]+mj[o]));
} else if(mf[o<<1|1]==-999999999)
{
mj[o<<1|1]=max(jia[o<<1|1]+mj[o],mj[o<<1|1]);
mf[o<<1|1]=mf[o];
}
//
if(fuzhi[o]!=-999999999)
{
jia[o<<1]=jia[o<<1|1]=0;
fuzhi[o<<1]=fuzhi[o<<1|1]=fuzhi[o];
max1[o<<1]=max1[o<<1|1]=fuzhi[o];
}
if(jia[o])
{
if(fuzhi[o<<1]!=-999999999)fuzhi[o<<1]+=jia[o];
else jia[o<<1]+=jia[o];
if(fuzhi[o<<1|1]!=-999999999)fuzhi[o<<1|1]+=jia[o];
else jia[o<<1|1]+=jia[o];
max1[o<<1]+=jia[o];
max1[o<<1|1]+=jia[o];
}
jia[o]=0; mj[o]=0;
fuzhi[o]=-999999999; mf[o]=-999999999;
}
void wen(int l,int r,int o)
{if(l!=r)down(o);
if(a<=l&&r<=b)
{
if(op==1)
{
ans=max(ans,max1[o]);
}
if(op==2)
{
ans=max(ans,max2[o]);
}
if(op==3)
{
fuzhi[o]=c; mf[o]=max(mf[o],c);
jia[o]=0;
max1[o]=c; max2[o]=max(max2[o],mf[o]);
}
if(op==4)
{
if(fuzhi[o]==-999999999)
{
jia[o]+=c; mj[o]=max(mj[o],jia[o]);
max1[o]+=c; max2[o]=max(max2[o],max1[o]);
}else
{
fuzhi[o]+=c; mf[o]=max(mf[o],fuzhi[o]);
max1[o]+=c; max2[o]=max(max1[o],max2[o]);
}
}
return;
} // if(l!=r)down(o);
int mid=(l+r)>>1;
if(a<=mid)wen(zuo);
if(b>mid)wen(you);
up(o);
}
int main()
{
scanf("%d",&n);
jian(1,n,1);
scanf("%d",&q);
for(i=1;i<=q;i++)
{
scanf("%c",&ch);while(ch=='\n')scanf("%c",&ch);
if(ch=='Q')
{
scanf("%d%d",&a,&b);
ans=-999999999;
op=1;
wen(1,n,1);
printf("%d\n",ans);
}
if(ch=='A')
{
scanf("%d%d",&a,&b);
ans=-999999999;
op=2;
wen(1,n,1);
printf("%d\n",ans);
}
if(ch=='P')
{
scanf("%d%d%d",&a,&b,&c);
ans=-999999999;
op=4;
wen(1,n,1);
}
if(ch=='C')
{
scanf("%d%d%d",&a,&b,&c);
ans=-999999999;
op=3;
wen(1,n,1);
}
}
}