3064: Tyvj 1518 CPU监控
Time Limit: 20 Sec Memory Limit: 256 MB[ Submit][ Status][ Discuss]
Description
Bob需要一个程序来监视CPU使用率。这是一个很繁琐的过程,为了让问题更加简单,Bob会慢慢列出今天会在用计算机时做什么事。
Bob会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用鼠标乱点之类的事,甚至会一脚踢掉电源……这些事有的会让做这件事的这段时间内CPU使用率增加或减少一个值;有的事还会直接让CPU使用率变为一个值。
当然Bob会询问:在之前给出的事件影响下,CPU在某段时间内,使用率最高是多少。有时候Bob还会好奇地询问,在某段时间内CPU曾经的最高使用率是多少。
为了使计算精确,使用率不用百分比而用一个整数表示。
不保证Bob的事件列表出了莫名的问题,使得使用率为负………………
Input
第一行一个正整数T,表示Bob需要监视CPU的总时间。
然后第二行给出T个数表示在你的监视程序执行之前,Bob干的事让CPU在这段时间内每个时刻的使用率达已经达到了多少。
第三行给出一个数E,表示Bob需要做的事和询问的总数。
接下来E行每行表示给出一个询问或者列出一条事件:
Q X Y:询问从X到Y这段时间内CPU最高使用率
A X Y:询问从X到Y这段时间内之前列出的事件使CPU达到过的最高使用率
P X Y Z:列出一个事件这个事件使得从X到Y这段时间内CPU使用率增加Z
C X Y Z:列出一个事件这个事件使得从X到Y这段时间内CPU使用率变为Z
时间的单位为秒,使用率没有单位。
X和Y均为正整数(X<=Y),Z为一个整数。
从X到Y这段时间包含第X秒和第Y秒。
保证必要运算在有符号32位整数以内。
Output
对于每个询问,输出一行一个整数回答。
Sample Input
-62 -83 -9 -70 79 -78 -31 40 -18 -5
20
A 2 7
A 4 4
Q 4 4
P 2 2 -74
P 7 9 -71
P 7 10 -8
A 10 10
A 5 9
C 1 8 10
Q 6 6
Q 8 10
A 1 7
P 9 9 96
A 5 5
P 8 10 -53
P 6 6 5
A 10 10
A 4 4
Q 1 5
P 4 9 -69
Sample Output
-70
-70
-5
79
10
10
79
79
-5
10
10
HINT
数据分布如下:
第1、2个数据保证T和E均小于等于1000
第3、4个数据保证只有Q类询问
第5、6个数据保证只有C类事件
第7、8个数据保证只有P类事件
全部数据保证T和E均小于等于100000
Source
#include<iostream>
#include<cstdio>
typedef long long ll;
#define inf 1e18
using namespace std;
const int N = 150005;
int n,m,a[N],ls[N*4],rs[N*4],id=0,root; char ch[5];
ll mx[N*4],f1[N*4],f2[N*4],m_x[N*4],f_1[N*4],f_2[N*4];
void update( int k ){
mx[k] = max(mx[ls[k]],mx[rs[k]]);
m_x[k] = max(m_x[ls[k]],m_x[rs[k]]);
}
void pushdown( int k ){
m_x[ls[k]] = max(m_x[ls[k]],max(f_2[k],mx[ls[k]]+f_1[k]));
if( f2[ls[k]] == -inf ) f_1[ls[k]] = max(f_1[ls[k]],f1[ls[k]]+f_1[k]);
else f_2[ls[k]] = max(f_2[ls[k]],f2[ls[k]]+f_1[k]);
if( f1[k] ){
if( f2[ls[k]] != -inf ) f2[ls[k]] += f1[k];
else f1[ls[k]] += f1[k];
mx[ls[k]] += f1[k];
}
if( f2[k] != -inf ){
mx[ls[k]] = f2[ls[k]] = f2[k];
f1[ls[k]] = 0;
}
f_1[ls[k]] = max(f_1[ls[k]],f1[ls[k]]);
f_2[ls[k]] = max(f_2[ls[k]],max(f2[k],f_2[k]));
//======================================================================================================
m_x[rs[k]] = max(m_x[rs[k]],max(f_2[k],mx[rs[k]]+f_1[k]));
if( f2[rs[k]] == -inf ) f_1[rs[k]] = max(f_1[rs[k]],f1[rs[k]]+f_1[k]);
else f_2[rs[k]] = max(f_2[rs[k]],f2[rs[k]]+f_1[k]);
if( f1[k] ){
if( f2[rs[k]] != -inf ) f2[rs[k]] += f1[k];
else f1[rs[k]] += f1[k];
mx[rs[k]] += f1[k];
}
if( f2[k] != -inf ){
mx[rs[k]] = f2[rs[k]] = f2[k];
f1[rs[k]] = 0;
}
f_1[rs[k]] = max(f_1[rs[k]],f1[rs[k]]);
f_2[rs[k]] = max(f_2[rs[k]],max(f2[k],f_2[k]));
//======================================================================================================
f_1[k] = f1[k] = 0;
f_2[k] = f2[k] = -inf;
}
void build( int &k, int l, int r ){
k = ++id; f1[k] = f_1[k] = 0; f2[k] = f_2[k] = -inf;
if( l == r ){
mx[k] = m_x[k] = (ll)a[l]; return;
}
int mid = (l+r)>>1;
build(ls[k],l,mid); build(rs[k],mid+1,r);
update(k);
}
void change( int k, int l, int r, int L, int R, ll x, int type ){
if( l != r ) pushdown(k);
if( L <= l && r <= R ){
if( !type ) mx[k] += x, f1[k] += x, f_1[k] += x;
else f2[k] = f_2[k] = mx[k] = x;
m_x[k] = max(mx[k],m_x[k]);
return;
}
int mid = (l+r)>>1;
if( mid >= L ) change( ls[k], l, mid, L, R, x, type );
if( mid < R ) change( rs[k], mid+1, r, L, R, x, type );
update(k);
}
ll query( int k, int l, int r, int L, int R, int type ){
if( l != k ) pushdown(k);
if( L <= l && R >= r ){ return type ? m_x[k] : mx[k]; }
int mid = (l+r)>>1; ll res = -inf;
if( mid >= L ) res = max(res,query(ls[k],l,mid,L,R,type));
if( mid < R ) res = max(res,query(rs[k],mid+1,r,L,R,type));
return res;
}
int main(){
scanf("%d",&n);
for( int i = 1; i <= n; i++ ) scanf("%d", &a[i]);
build(root,1,n); scanf("%d", &m);
for( int i = 1,l,r,x; i <= m; i++ ){
scanf("%s", ch);
if( ch[0] == 'Q' ){ scanf("%d%d", &l, &r); printf("%lld\n",query(root,1,n,l,r,0));}
if( ch[0] == 'A' ){ scanf("%d%d", &l, &r); printf("%lld\n",query(root,1,n,l,r,1));}
if( ch[0] == 'P' ){ scanf("%d%d%d", &l, &r, &x); change(root,1,n,l,r,(ll)x,0);}
if( ch[0] == 'C' ){ scanf("%d%d%d", &l, &r, &x); change(root,1,n,l,r,(ll)x,1);}
}
return 0;
}