Q0230 CPU 监控题解
CPU 监控
题目背景
Bob 家的机子很烂……真的很烂……
以至于看视频或者跑邪恶的暴力程序的时候,由于 CPU 使用率持续过高而宕机。
题目描述
Bob 需要一个程序来监视 CPU 使用率。这是一个很繁琐的过程,为了让问题更加简单,Bob 会慢慢列出今天会在用计算机时做什么事。
Bob 会干很多事,除了跑暴力程序看视频之外,还会做出去玩玩和用鼠标乱点之类的事,甚至会一脚踢掉电源……这些事有的会让做这件事的这段时间内 CPU 使用率增加或减少一个值;有的事还会直接让 CPU 使用率变为一个值。
当然 Bob 会询问:在之前给出的事件影响下,CPU 在某段时间内,使用率最高是多少。有时候 Bob 还会好奇地询问,在某段时间内 CPU 曾经的最高使用率是多少。
为了使计算精确,使用率不用百分比而用一个整数表示。
不保证 Bob 的事件列表出了莫名的问题,使得使用率为负………………
输入格式
第一行一个正整数 TT,表示 Bob 需要监视 CPU 的总时间。
然后第二行给出 TT 个数表示在你的监视程序执行之前,Bob 干的事让 CPU 在这段时间内每个时刻的使用率达已经达到了多少。
第三行给出一个整数 EE,表示 Bob 需要做的事和询问的总数。
接下来 EE 行每行表示给出一个询问或者列出一条事件:
Q X Y:询问从 XX 到 YY 这段时间内 CPU 最高使用率。A X Y:询问从 XX 到 YY 这段时间内之前列出的事件使 CPU 达到过的最高使用率。P X Y Z:列出一个事件这个事件使得从 XX 到 YY 这段时间内 CPU 使用率增加 ZZ。C X Y Z:列出一个事件这个事件使得从 XX 到 YY 这段时间内 CPU 使用率变为 ZZ。
时间的单位为秒,使用率没有单位。
XX 和 YY 均为正整数(X≤YX≤Y),ZZ 为一个整数。
从 XX 到 YY 这段时间包含第 XX 秒和第 YY 秒。
保证必要运算在有符号 32 位整数以内。
输出格式
对于每个询问,输出一行一个整数回答。
样例 #1
输入数据 1
10
-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
输出数据 1
79
-70
-70
-5
79
10
10
79
79
-5
10
10
提示
数据分布如下:
第 1,21,2 个数据保证 TT 和 EE 均小于等于 103103。
第 3,43,4 个数据保证只有 Q 类询问。
第 5,65,6 个数据保证只有 C 类事件。
第 7,87,8 个数据保证只有 P 类事件。
对于 100%100% 的数据,1≤T,E≤1051≤T,E≤105,1≤X≤Y<T1≤X≤Y<T,−231≤Z<231−231≤Z<231。
思路
线段树。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long n,m,a[1000006],siz[4000006],u,ll,rr;
long long te[4000006],lz[4000006],lz2[4000006],clz[4000006],xx;
long long te2[4000006],lz1[4000006],lz21[4000006],clz1[4000006],xx1;
char ch;
void alz(int a1,long long v1,long long v2){
if(clz[a1]==1){
lz21[a1]=max(v2,lz21[a1]);
te2[a1]=max(v2,te2[a1]);
}
else{
clz[a1]=1;
lz21[a1]=v2;
te2[a1]=max(v2,te2[a1]);
}
te[a1]=lz2[a1]=v1;
}//a1打标记值v
void alz2(int a1,long long v1,long long v2){
if(clz[a1]==1){
lz21[a1]=max(lz2[a1]+v2,lz21[a1]);
te2[a1]=max(te[a1]+v2,te2[a1]);
lz2[a1]+=v1;
te[a1]+=v1;
}
else{
lz1[a1]=max(lz[a1]+v2,lz1[a1]);
te2[a1]=max(te[a1]+v2,te2[a1]);
lz[a1]+=v1;
te[a1]+=v1;
}
}//a1打标记值v
void dow(int a1){
alz2(a1*2,lz[a1],lz1[a1]);
alz2(a1*2+1,lz[a1],lz1[a1]);
lz[a1]=lz1[a1]=0;
if(clz[a1]==1){
alz(a1*2,lz2[a1],lz21[a1]);
alz(a1*2+1,lz2[a1],lz21[a1]);
}
clz[a1]=0;
lz2[a1]=0;
lz21[a1]=0;
}//a1下发标记至儿子
void bu(int a1,int l,int r){
siz[a1]=r-l+1;
if(l==r){
te[a1]=a[l];
te2[a1]=a[l];
return ;
}
int mid=(l+r)/2;
bu(a1*2,l,mid);
bu(a1*2+1,mid+1,r);
te[a1]=max(te[a1*2],te[a1*2+1]);
te2[a1]=max(te2[a1*2],te2[a1*2+1]);
return ;
}//l~r建树节点a1
void ci(int a1,int l,int r,int x,int y,long long v){
if(l>=x&&r<=y){
alz2(a1,v,v);
return ;
}
int mid=(l+r)/2;
dow(a1);
if(x<=mid){
ci(a1*2,l,mid,x,y,v);
}
if(mid+1<=y){
ci(a1*2+1,mid+1,r,x,y,v);
}
te[a1]=max(te[a1*2],te[a1*2+1]);
te2[a1]=max(te2[a1*2],te2[a1*2+1]);
//if(clz[a1*2]==1&&clz[a1*2+1]==1) clz[a1]=1;
return ;
}//x~y区间加v至l~r区间a1点
void ci2(int a1,int l,int r,int x,int y,long long v){
if(l>=x&&r<=y){
alz(a1,v,v);
return ;
}
int mid=(l+r)/2;
dow(a1);
if(x<=mid){
ci2(a1*2,l,mid,x,y,v);
}
if(mid+1<=y){
ci2(a1*2+1,mid+1,r,x,y,v);
}
te[a1]=max(te[a1*2],te[a1*2+1]);
te2[a1]=max(te2[a1*2],te2[a1*2+1]);
//if(clz[a1*2]==1&&clz[a1*2+1]==1) clz[a1]=1;
return ;
}//x~y区间加v至l~r区间a1点
long long co(int a1,int l,int r,int x,int y){
if(x<=l&&r<=y){
return te[a1];
}
int mid=(l+r)/2;
long long dbdb=-1e18-7;
dow(a1);
if(mid>=x){
dbdb=max(dbdb,co(a1*2,l,mid,x,y));
}
if(mid+1<=y){
dbdb=max(dbdb,co(a1*2+1,mid+1,r,x,y));
}
//if(clz[a1*2]==1&&clz[a1*2+1]==1) clz[a1]=1;
return dbdb;
}//x~y区间问至l~r区间a1点
long long co2(int a1,int l,int r,int x,int y){
if(x<=l&&r<=y){
return te2[a1];
}
int mid=(l+r)/2;
long long dbdb=-1e18-7;
dow(a1);
if(mid>=x){
dbdb=max(dbdb,co2(a1*2,l,mid,x,y));
}
if(mid+1<=y){
dbdb=max(dbdb,co2(a1*2+1,mid+1,r,x,y));
}
//if(clz[a1*2]==1&&clz[a1*2+1]==1) clz[a1]=1;
return dbdb;
}//x~y区间问至l~r区间a1点
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=4*n;i++){
lz2[i]=0;
lz21[i]=0;
}
bu(1,1,n);
cin>>m;
for(int i=1;i<=m;i++){
cin>>ch;
if(ch=='P'){
cin>>ll>>rr>>xx;
ci(1,1,n,ll,rr,xx);
}
else if(ch=='C'){
cin>>ll>>rr>>xx;
ci2(1,1,n,ll,rr,xx);
}
else if(ch=='Q'){
cin>>ll>>rr;
cout<<co(1,1,n,ll,rr)<<endl;
}
else{
cin>>ll>>rr;
cout<<co2(1,1,n,ll,rr)<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号