#include <stdio.h>
int main()
{
puts("转载请注明出处谢谢");
puts("http://blog.youkuaiyun.com/vmurder/article/details/43271091");
}
题解:显然是裸的线段树,连区间合并都没有,更别提可持久化了。。。
水得一比,但是也相当恶心。。
维护一下:
目前线段 最大值、覆盖值、增加值、
历史线段 最大值、覆盖值、增加值。
然后覆盖值是赋-inf还是再加个flag记录有没有随便了。
总之很恶心,昨天晚上调了好久好久都没调过。
对了,这种恶心的东西不妨分多个线段树维护。
o(︶︿︶)o 、本来就感冒,晚上还熬夜,作死0:30去操场跑个步还撞到了铁门上。
Qwq。
贴代码吧,虽然没什么意义。
呃,我的define不是很难看的,不用抗拒的说~~wWW
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define inf 0x3f3f3f3f
#define ls note<<1
#define rs note<<1|1
#define N 101000
#define his hs[note]
#define my s[note]
using namespace std;
struct Segment_Tree
{
int x,cover,add;
}s[N<<2],hs[N<<2];
inline void checkmax(int &x,int y){x=max(x,y);}
inline void h_add(int note,int v)
{
checkmax(his.x,my.x+v);
if(my.cover>-inf)checkmax(his.cover,my.cover+v);
else checkmax(his.add,my.add+v);
}
inline void h_cover(int note,int v)
{
checkmax(his.x,v);
checkmax(his.cover,v);
}
inline void m_add(int note,int v)
{
checkmax(his.x,my.x+=v);
if(my.cover>-inf)checkmax(his.cover,my.cover+=v);
else checkmax(his.add,my.add+=v);
}
inline void m_cover(int note,int v)
{
checkmax(his.x,my.x=v);
checkmax(his.cover,my.cover=v);
my.add=0;
}
inline void pushdown(int note)
{
if(his.add)
{
h_add(ls,his.add);
h_add(rs,his.add);
his.add=0;
}
if(his.cover>-inf)
{
h_cover(ls,his.cover);
h_cover(rs,his.cover);
his.cover=-inf;
}
if(my.add)
{
m_add(ls,my.add);
m_add(rs,my.add);
my.add=0;
}
if(my.cover>-inf)
{
m_cover(ls,my.cover);
m_cover(rs,my.cover);
my.cover=-inf;
}
}
inline void pushup(int note)
{
my.x=max(s[ls].x,s[rs].x);
checkmax(his.x,max(hs[ls].x,hs[rs].x));
}
void build(int note,int l,int r)
{
my.cover=his.cover=-inf;
if(l==r)
{
scanf("%d",&my.x),his.x=my.x;
return ;
}
int mid=l+r>>1;
build(ls,l,mid),build(rs,mid+1,r);
his.x=-inf,pushup(note);
}
void add(int note,int L,int R,int l,int r,int x)
{
if(l<=L&&R<=r){m_add(note,x);return ;}
pushdown(note);
int mid=L+R>>1;
if(l<=mid)add(ls,L,mid,l,r,x);
if(r>mid)add(rs,mid+1,R,l,r,x);
pushup(note);
}
void cover(int note,int L,int R,int l,int r,int x)
{
if(l<=L&&R<=r){m_cover(note,x);return ;}
pushdown(note);
int mid=L+R>>1;
if(l<=mid)cover(ls,L,mid,l,r,x);
if(r>mid)cover(rs,mid+1,R,l,r,x);
pushup(note);
}
int query(int note,int L,int R,int l,int r)
{
if(l<=L&&R<=r)return my.x;
pushdown(note);
int mid=L+R>>1,ans=-inf;
if(l<=mid)ans=max(ans,query(ls,L,mid,l,r));
if(r>mid)ans=max(ans,query(rs,mid+1,R,l,r));
return ans;
}
int ask(int note,int L,int R,int l,int r)
{
if(l<=L&&R<=r)return his.x;
pushdown(note);
int mid=L+R>>1,ans=-inf;
if(l<=mid)ans=max(ans,ask(ls,L,mid,l,r));
if(r>mid)ans=max(ans,ask(rs,mid+1,R,l,r));
return ans;
}
int n,m;
int main()
{
char opt[5];
int i,j,k;
int a,b,c;
scanf("%d",&n);
build(1,1,n);
for(scanf("%d",&m);m--;)
{
scanf("%s%d%d",opt,&a,&b);
if(opt[0]=='Q')printf("%d\n",query(1,1,n,a,b));
else if(opt[0]=='A')printf("%d\n",ask(1,1,n,a,b));
else if(opt[0]=='P')
{
scanf("%d",&c);
add(1,1,n,a,b,c);
}
else if(opt[0]=='C')
{
scanf("%d",&c);
cover(1,1,n,a,b,c);
}
}
return 0;
}