3064: Tyvj 1518 CPU监控
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 1401 Solved: 548
[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
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
Sample Output
79
-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
sol:
这题可以说是有点蛋疼了
先是写了个简单线段树,后来发现简单的lazy tag会丢失历史信息。
思考这么一个问题。我们当前时刻的标记正常打,然后额外记录一个add,cov的标记,add表示从上一个下放标记的时候到现在最大的add标记的值,那么这个值下放后可以和下面的值相加得到cov之前的最大值。容易发现这个标记是很容易合并的,更新儿子的时候,add[lc]=max(add[k]+nowadd[k])。第二个阶段,如果一个节点被打上了历史的cover标记的话, 因为我们的add实际上是为了给子节点中的以前的值提供更新,但是如果一个节点被打上了cov标记,那么在这个节点上面打加法标记的时候,就不能加在add上了,因为实际上子节点的值已经变了,所以直接打在cov上面。
这题写了2遍都没过,第3遍去网上抄了份代码,无耻的发了上来
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#define his hs[k]
#define my now[k]
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int N=410000;
const int inf=1e9;
int n,m;
inline int read()
{
char c;
int res,flag=0;
while((c=getchar())>'9'||c<'0') if(c=='-')flag=1;
res=c-'0';
while((c=getchar())>='0'&&c<='9') res=(res<<3)+(res<<1)+c-'0';
return flag?-res:res;
}
struct Segment_Tree
{
int x,cover,add;
}now[N<<2],hs[N<<2];
inline void simplex(int &x,int y){x=max(x,y);}
inline void h_add(int k,int v)
{
simplex(his.x,my.x+v);
if(my.cover>-inf)simplex(his.cover,my.cover+v);
else simplex(his.add,my.add+v);
}
inline void h_cover(int k,int v)
{
simplex(his.x,v);
simplex(his.cover,v);
}
inline void m_add(int k,int v)
{
simplex(his.x,my.x+=v);
if(my.cover>-inf)simplex(his.cover,my.cover+=v);
else simplex(his.add,my.add+=v);
}
inline void m_cover(int k,int v)
{
simplex(his.x,my.x=v);
simplex(his.cover,my.cover=v);
my.add=0;
}
inline void pushdown(int k)
{
if(his.add)
{
h_add(ls,his.add);
h_add(rs,his.add);
his.add=0;
}
if(his.cover>-inf)
{
h_cover(ls,his.cover);
h_cover(rs,his.cover);
his.cover=-inf;
}
if(my.add)
{
m_add(ls,my.add);
m_add(rs,my.add);
my.add=0;
}
if(my.cover>-inf)
{
m_cover(ls,my.cover);
m_cover(rs,my.cover);
my.cover=-inf;
}
}
inline void pushup(int k)
{
my.x=max(now[ls].x,now[rs].x);
simplex(his.x,max(hs[ls].x,hs[rs].x));
}
void build(int k,int l,int r)
{
my.cover=his.cover=-inf;
if(l==r)
{
scanf("%d",&my.x),his.x=my.x;
return ;
}
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
his.x=-inf,pushup(k);
}
void add(int k,int L,int R,int l,int r,int x)
{
if(l<=L&&R<=r){m_add(k,x);return ;}
pushdown(k);
int mid=L+R>>1;
if(l<=mid)add(ls,L,mid,l,r,x);
if(r>mid)add(rs,mid+1,R,l,r,x);
pushup(k);
}
void cover(int k,int L,int R,int l,int r,int x)
{
if(l<=L&&R<=r){m_cover(k,x);return ;}
pushdown(k);
int mid=L+R>>1;
if(l<=mid)cover(ls,L,mid,l,r,x);
if(r>mid)cover(rs,mid+1,R,l,r,x);
pushup(k);
}
int query(int k,int L,int R,int l,int r)
{
if(l<=L&&R<=r)return my.x;
pushdown(k);
int mid=L+R>>1,ans=-inf;
if(l<=mid)ans=max(ans,query(ls,L,mid,l,r));
if(r>mid)ans=max(ans,query(rs,mid+1,R,l,r));
return ans;
}
int ask(int k,int L,int R,int l,int r)
{
if(l<=L&&R<=r)return his.x;
pushdown(k);
int mid=L+R>>1,ans=-inf;
if(l<=mid)ans=max(ans,ask(ls,L,mid,l,r));
if(r>mid)ans=max(ans,ask(rs,mid+1,R,l,r));
return ans;
}
int main()
{
// freopen("3064.in","r",stdin);
// freopen("3064h.out","w",stdout);
char opt[5];
scanf("%d",&n);
build(1,1,n);
m=read();
int a,b,c;
while(m--)
{
scanf("%s",opt);
a=read();
b=read();
if(opt[0]=='Q') printf("%d\n",query(1,1,n,a,b));
if(opt[0]=='A') printf("%d\n",ask(1,1,n,a,b));
if(opt[0]=='P')
{
scanf("%d",&c);
add(1,1,n,a,b,c);
}
if(opt[0]=='C')
{
scanf("%d",&c);
cover(1,1,n,a,b,c);
}
}
}