【bzoj3064】 CPU監控

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

題意

  給出一個長度爲$n$的數列$A$,同時定義一個輔助數組$B$,$B$開始與$A$徹底相同。接下來進行$m$次操做, 有4種類型:node

  1. 區間加法
  2. 區間覆蓋
  3. 查詢$A$的區間最值
  4. 查詢$B$的區間最值

Solution

  參考吉利論文。ios

  最噁心的就是覆蓋標記和加減標記的合併=  =,必定要想清楚全部狀況。數組

細節

  代碼略醜=  =ui

代碼

// 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;
}
相關文章
相關標籤/搜索