【bzoj3064】 CPU监控

http://www.lydsy.com/JudgeOnline/problem.php?id=3064 (题目链接)

题意

  给出一个长度为$n$的数列$A$,同时定义一个辅助数组$B$,$B$开始与$A$完全相同。接下来进行$m$次操作, 有4种类型:

  1. 区间加法
  2. 区间覆盖
  3. 查询$A$的区间最值
  4. 查询$B$的区间最值

Solution

  参考吉利论文。

  最恶心的就是覆盖标记和加减标记的合并=  =,一定要想清楚所有情况。

细节

  代码略丑=  =

代码

// bzoj3938
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf (1ll<<30)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;

const int maxn=100010;
int n,m,a[maxn];
char ch[100];
struct node {int l,r,nadd,padd,ncov,pcov,nmx,pmx;}tr[maxn<<2];

void pushup(int k) {
	tr[k].nmx=max(tr[k<<1].nmx,tr[k<<1|1].nmx);
	tr[k].pmx=max(tr[k<<1].pmx,tr[k<<1|1].pmx);
}
void pushdown(int k) {
	for (int x,i=0;x=k<<1|i,i<2;i++) {
		tr[x].pmx=max(tr[x].pmx,max(tr[k].padd+tr[x].nmx,tr[k].pcov));
		if (tr[k].ncov==-inf) {
			tr[x].nmx+=tr[k].nadd;
			if (tr[x].ncov==-inf) tr[x].padd=max(tr[x].padd,tr[x].nadd+tr[k].padd),tr[x].nadd+=tr[k].nadd;
			else tr[x].pcov=max(tr[x].pcov,tr[x].ncov+tr[k].padd),tr[x].ncov=tr[x].nmx;
		}
		else {
			if (tr[x].ncov==-inf) tr[x].padd=max(tr[x].padd,tr[x].nadd+tr[k].padd);
			else tr[x].pcov=max(tr[x].pcov,tr[x].nmx+tr[k].padd);
			tr[x].nmx=tr[x].ncov=tr[k].ncov,tr[x].pcov=max(tr[x].pcov,tr[k].pcov);
		}
	}
	tr[k].ncov=tr[k].pcov=-inf;tr[k].nadd=tr[k].padd=0;
}
void build(int k,int s,int t) {
	tr[k].l=s;tr[k].r=t;
	tr[k].ncov=tr[k].pcov=-inf;
	if (s==t) {tr[k].nmx=tr[k].pmx=a[s];return;}
	int mid=(s+t)>>1;
	build(k<<1,s,mid);
	build(k<<1|1,mid+1,t);
	pushup(k);
}
int query(int k,int s,int t,int op) {
	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
	if (l==s && r==t) return op ? tr[k].pmx : tr[k].nmx;
	pushdown(k);
	if (t<=mid) return query(k<<1,s,t,op);
	else if (s>mid) return query(k<<1|1,s,t,op);
	else return max(query(k<<1,s,mid,op),query(k<<1|1,mid+1,t,op));
}
void modify(int k,int s,int t,int val,int op) {
	int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
	if (l==s && r==t) {
		if (op) {
			tr[k].pmx=max(tr[k].pmx,tr[k].nmx=val);
			tr[k].pcov=max(tr[k].pcov,tr[k].ncov=val);
		}
		else {
			tr[k].pmx=max(tr[k].pmx,tr[k].nmx+=val);
			if (tr[k].ncov==-inf) tr[k].padd=max(tr[k].padd,tr[k].nadd+=val);
			else tr[k].pcov=max(tr[k].pcov,tr[k].ncov=tr[k].nmx);
		}
		return;
	}
	pushdown(k);
	if (t<=mid) modify(k<<1,s,t,val,op);
	else if (s>mid) modify(k<<1|1,s,t,val,op);
	else modify(k<<1,s,mid,val,op),modify(k<<1|1,mid+1,t,val,op);
	pushup(k);
}
int main() {
	scanf("%d",&n);
	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,1,n);
	scanf("%d",&m);
	for (int x,y,z,i=1;i<=m;i++) {
		scanf("%s%d%d",ch,&x,&y);
		if (ch[0]=='Q') printf("%d\n",query(1,x,y,0));
		if (ch[0]=='A') printf("%d\n",query(1,x,y,1));
		if (ch[0]=='P') scanf("%d",&z),modify(1,x,y,z,0);
		if (ch[0]=='C') scanf("%d",&z),modify(1,x,y,z,1);
	}
	return 0;
}

 

posted @ 2017-04-05 08:01  MashiroSky  阅读(463)  评论(0编辑  收藏  举报