#include <stdio.h> int main() { puts("转载请注明出处谢谢"); puts("http://blog.csdn.net/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; }