P4314 CPU监控 题解

P4314 CPU监控 题解

题面

历史最值线段树。考虑到每个区间的操作大概是这样:先是一些加法操作,然后有一次赋值,在这次赋值之后所有的操作都可以表示成赋值。所以维护两类标记,一类表示前面的加法,另一类表示赋值,记录一下这个点有没有开始赋值即可。代码及其难调,建议理清思路再写……

点击查看代码
#include<iostream>#include<cstdio>using namespace std;typedef long long ll;const int N=1e5+13;const ll INF=0x3f3f3f3f3f3f3f3fll;inline ll max(const ll &a,const ll &b){return a>b?a:b;}int n,a[N],m;struct SegTree{int l,r;ll add,preadd,max,premax,set,preset;bool state;}t[N<<2];#define ls p<<1#define rs p<<1|1#define mid ((t[p].l+t[p].r)>>1)inline void refresh(int p){t[p].max=max(t[ls].max,t[rs].max);t[p].premax=max(t[ls].premax,t[rs].premax);}void build(int p,int l,int r){t[p].l=l,t[p].r=r,t[p].max=t[p].premax=-INF;if(l==r){t[p].max=t[p].premax=a[l];return;}build(ls,l,mid);build(rs,mid+1,r);refresh(p);}inline void pushup_set(int p,ll x,ll px){if(!t[p].state){t[p].state=1;t[p].preset=px;t[p].premax=max(t[p].premax,px);}else{t[p].preset=max(t[p].preset,px);t[p].premax=max(t[p].premax,px);}t[p].set=t[p].max=x;}inline void pushup_add(int p,ll x,ll px){if(t[p].state){t[p].preset=max(t[p].preset,t[p].set+px);t[p].premax=max(t[p].premax,t[p].max+px);t[p].set+=x,t[p].max+=x;}else{t[p].preadd=max(t[p].preadd,t[p].add+px);t[p].premax=max(t[p].premax,t[p].max+px);t[p].add+=x,t[p].max+=x;}}inline void pushdown(int p){pushup_add(ls,t[p].add,t[p].preadd);pushup_add(rs,t[p].add,t[p].preadd);t[p].add=t[p].preadd=0;if(t[p].state){pushup_set(ls,t[p].set,t[p].preset);pushup_set(rs,t[p].set,t[p].preset);t[p].state=0,t[p].set=t[p].preset=0;}}void update(int p,int l,int r,ll x){if(l<=t[p].l&&t[p].r<=r) return pushup_add(p,x,x);pushdown(p);if(l<=mid) update(ls,l,r,x);if(r>mid) update(rs,l,r,x);refresh(p);}void modify(int p,int l,int r,ll x){if(l<=t[p].l&&t[p].r<=r) return pushup_set(p,x,x);pushdown(p);if(l<=mid) modify(ls,l,r,x);if(r>mid) modify(rs,l,r,x);refresh(p);}ll query_max(int p,int l,int r){if(l<=t[p].l&&t[p].r<=r) return t[p].max;pushdown(p);ll res=-INF;if(l<=mid) res=max(res,query_max(ls,l,r));if(r>mid) res=max(res,query_max(rs,l,r));return res;}ll query_pre(int p,int l,int r){if(l<=t[p].l&&t[p].r<=r) return t[p].premax;pushdown(p);ll res=-INF;if(l<=mid) res=max(res,query_pre(ls,l,r));if(r>mid) res=max(res,query_pre(rs,l,r));return res;}int main(){scanf("%d",&n);for(int i=1;i<=n;++i) scanf("%d",&a[i]);build(1,1,n);scanf("%d",&m);while(m--){char op[2];int x,y,z;scanf("%s%d%d",op,&x,&y);switch(op[0]){case 'Q':printf("%lld\n",query_max(1,x,y));break;case 'A':printf("%lld\n",query_pre(1,x,y));break;case 'P':scanf("%d",&z);update(1,x,y,z);break;case 'C':scanf("%d",&z);modify(1,x,y,z);break;}}return 0;}
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部