bzoj3064 Tyvj 1518 CPU监控

http://www.elijahqi.win/2018/01/13/bzoj3064-tyvj-1518-cpu%e7%9b%91%e6%8e%a7/
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

本来想自己yy 无奈太菜yy错了orz但是还是膜了其他blog的代码 很久 打 了两遍 感觉理解深刻一些了

线段树每个节点维护六个值 这些历史值我肯定是>=我现在节点上的值的

1、历史最大覆盖值2、历史最大值3、历史增量最大值4、当前覆盖值5、当前最大值6、当前增量 在建树的时候注意update之前需要把last_max变成-inf 因为我想要的历史最大值应该是可能出现在三个区间即 now now->left now->right 由于存在负数所以建树的时候我需要在更新之前把last_max改为-inf 对于insert1和change两个操作 如果上面有改动都会先将历史最大值完全下放 然后一气update

在查询最大值和历史最大值的时候比较方便就和一般线段树查询一样即可 注意都得进行下放操作

下放操作分为几步1、将历史最大增量下放 下放到左右两个子树分别和他们的历史最大值与 该子树增量+该节点的历史最大增量比较 做出该叶子节点的历史最大值 如果节点被完全覆盖 就要比较一下历史最大覆盖与现在的关系 反之需要比较一下该叶子节点的历史增量的变化

2、将历史最大覆盖下放

直接比较覆盖值和该叶子节点的历史最大值 比较一下该叶子节点的历史最大覆盖值 注意这里不需要判断是否历史上被覆盖过 因为我是下放覆盖值 且需注意直接把该节点的历史最大覆盖和叶子节点的历史最大覆盖比较即可

3、将当前增量下放 基本同线段树基本操作 同1操作 注意将增量加至叶子结点

4、将当前覆盖下放 与2操作基本相同 注意将当前覆盖 覆盖叶子节点
等待回来膜一下icefox巨佬的短小精悍的代码 qwq


#include<cstdio>
#include<algorithm>
#define N 100010
#define inf 0x3f3f3f3f
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
    while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
    return x*f;
}
struct node{
    int left,right,last_max,last_cover,last_add,cover,max,add;//cover==-inf表示没有被完全覆盖 
}tree[N<<1];
int num,n,root;
inline void update(int x){
    int l=tree[x].left,r=tree[x].right;
    tree[x].last_max=max(tree[l].last_max,tree[r].last_max);
    tree[x].max=max(tree[l].max,tree[r].max);
}
inline void build(int &x,int l,int r){
    x=++num;tree[x].cover=tree[x].last_cover=-inf;
    if (l==r){tree[x].max=tree[x].last_max=read();return;}
    int mid=l+r>>1;build(tree[x].left,l,mid);build(tree[x].right,mid+1,r);
    tree[x].last_max=-inf;update(x);
}
inline void add(int x,int v){
    tree[x].last_max=max(tree[x].last_max,tree[x].max+=v);
    if (tree[x].cover>-inf) tree[x].last_cover=max(tree[x].last_cover,tree[x].cover+=v);
    else tree[x].last_add=max(tree[x].last_add,tree[x].add+=v);
}
inline void change1(int x,int v){
    tree[x].last_max=max(tree[x].last_max,tree[x].max=v);tree[x].add=0;
    tree[x].last_cover=max(tree[x].last_cover,tree[x].cover=v);
}
inline void l_add(int x,int v){
    tree[x].last_max=max(tree[x].last_max,tree[x].max+v);
    if (tree[x].cover>-inf) tree[x].last_cover=max(tree[x].last_cover,tree[x].cover+v);
    else tree[x].last_add=max(tree[x].last_add,tree[x].add+v);
}
inline void l_change(int x,int v){
    tree[x].last_max=max(tree[x].last_max,v);
    tree[x].last_cover=max(tree[x].last_cover,v);
}
inline void pushdown(int x){
    if (tree[x].last_add)
        l_add(tree[x].left,tree[x].last_add),l_add(tree[x].right,tree[x].last_add),tree[x].last_add=0;
    if (tree[x].last_cover>-inf)
        l_change(tree[x].left,tree[x].last_cover),l_change(tree[x].right,tree[x].last_cover),tree[x].last_cover=-inf;
    if (tree[x].add)
        add(tree[x].left,tree[x].add),add(tree[x].right,tree[x].add),tree[x].add=0;
    if (tree[x].cover>-inf)
        change1(tree[x].left,tree[x].cover),change1(tree[x].right,tree[x].cover),tree[x].cover=-inf;
}
inline int query(int x,int l,int r,int l1,int r1){
    if (l1<=l&&r1>=r) return tree[x].max;
    int mid=l+r>>1;pushdown(x);int tmp=-inf;
    if (l1<=mid) tmp=max(tmp,query(tree[x].left,l,mid,l1,r1));
    if (r1>mid) tmp=max(tmp,query(tree[x].right,mid+1,r,l1,r1));return tmp;
}
inline int query1(int x,int l,int r,int l1,int r1){
    if (l1<=l&&r1>=r) return tree[x].last_max;
    int mid=l+r>>1;pushdown(x);int tmp=-inf;
    if (l1<=mid) tmp=max(tmp,query1(tree[x].left,l,mid,l1,r1));
    if (r1>mid) tmp=max(tmp,query1(tree[x].right,mid+1,r,l1,r1));return tmp;
}
inline void change(int x,int l,int r,int l1,int r1,int v){
    if (l1<=l&&r1>=r) {change1(x,v);return;}
    int mid=l+r>>1;pushdown(x);
    if (l1<=mid) change(tree[x].left,l,mid,l1,r1,v);
    if (r1>mid) change(tree[x].right,mid+1,r,l1,r1,v);update(x);
}
inline void insert1(int x,int l,int r,int l1,int r1,int v){
    if (l1<=l&&r1>=r) {add(x,v);return;}
    int mid=l+r>>1;pushdown(x);
    if (l1<=mid) insert1(tree[x].left,l,mid,l1,r1,v);
    if (r1>mid) insert1(tree[x].right,mid+1,r,l1,r1,v);update(x); 
}
int main(){
    freopen("bzoj3064.in","r",stdin);
    n=read();build(root,1,n);int m=read();
    for (int i=1;i<=m;++i){
        char ch=gc();while(ch!='A'&&ch!='Q'&&ch!='P'&&ch!='C') ch=gc();
        if (ch=='Q') {int l=read(),r=read();printf("%d\n",query(root,1,n,l,r));}
        if (ch=='A') {int l=read(),r=read();printf("%d\n",query1(root,1,n,l,r));}
        if (ch=='P') {int l=read(),r=read(),v=read();insert1(root,1,n,l,r,v);}
        if (ch=='C') {int l=read(),r=read(),v=read();change(root,1,n,l,r,v);}
    }
    return 0;
}

#include<cstdio>
#include<algorithm>
#define N 110000
#define inf 0x3f3f3f3f
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=gc();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
    return x*f;
}
struct node{
    int left,right,v,max,add,last_max,last_v,last_add;
}tree[N<<1];
int n,m,a[N],root,num;
inline void update(int x){
    int l=tree[x].left,r=tree[x].right;
    tree[x].max=max(tree[l].max,tree[r].max);
    tree[x].last_max=max(tree[l].last_max,tree[r].last_max);
}
inline void build(int &x,int l,int r){
    x=++num;tree[x].v=tree[x].last_v=-inf;
    if (l==r){
        tree[x].max=tree[x].last_max=a[l];return;
    }int mid=l+r>>1;
    build(tree[x].left,l,mid);build(tree[x].right,mid+1,r);
    tree[x].last_max=-inf;update(x);
}
inline void add(int x,int v){
    tree[x].last_max=max(tree[x].last_max,tree[x].max+=v);
    if (tree[x].v>-inf) tree[x].last_v=max(tree[x].last_v,tree[x].v+=v);
    else tree[x].last_add=max(tree[x].last_add,tree[x].add+=v);
}
inline void change1(int x,int v){
    tree[x].last_max=max(tree[x].last_max,tree[x].max=v);tree[x].last_v=max(tree[x].last_v,tree[x].v=v);
    tree[x].add=0;
}
inline void ladd(int x,int v){
    tree[x].last_max=max(tree[x].last_max,tree[x].max+v);
    if (tree[x].v>-inf) tree[x].last_v=max(tree[x].last_v,tree[x].v+v);
    else tree[x].last_add=max(tree[x].last_add,tree[x].add+v);
}
inline void lc(int x,int v){
    tree[x].last_max=max(tree[x].last_max,v);tree[x].last_v=max(tree[x].last_v,v);
}
inline void pushdown(int x){
    if (tree[x].last_add)
        ladd(tree[x].left,tree[x].last_add),ladd(tree[x].right,tree[x].last_add),tree[x].last_add=0;
    if (tree[x].last_v>-inf)
        lc(tree[x].left,tree[x].last_v),lc(tree[x].right,tree[x].last_v),tree[x].last_v=-inf;
    if (tree[x].add) add(tree[x].left,tree[x].add),add(tree[x].right,tree[x].add),tree[x].add=0;
    if (tree[x].v>-inf) change1(tree[x].left,tree[x].v),change1(tree[x].right,tree[x].v),tree[x].v=-inf;
}
inline void insert1(int x,int l,int r,int l1,int r1,int v){
    if (l1<=l&&r1>=r){add(x,v);return;}
    int mid=l+r>>1;pushdown(x);
    if (l1<=mid) insert1(tree[x].left,l,mid,l1,r1,v);
    if (r1>mid) insert1(tree[x].right,mid+1,r,l1,r1,v);update(x);
}
inline void change(int x,int l,int r,int l1,int r1,int v){
    if (l1<=l&&r1>=r){change1(x,v);return;}
    int mid=l+r>>1;pushdown(x);
    if (l1<=mid) change(tree[x].left,l,mid,l1,r1,v);
    if (r1>mid) change(tree[x].right,mid+1,r,l1,r1,v);update(x);
}
inline int query(int x,int l,int r,int l1,int r1){
    if (l1<=l&&r1>=r) return tree[x].max;
    int mid=l+r>>1;pushdown(x);int tmp=-inf;
    if (l1<=mid) tmp=max(tmp,query(tree[x].left,l,mid,l1,r1));
    if (r1>mid) tmp=max(tmp,query(tree[x].right,mid+1,r,l1,r1));return tmp;
}
inline int query1(int x,int l,int r,int l1,int r1){
    if(l1<=l&&r1>=r) return tree[x].last_max;
    int mid=l+r>>1;pushdown(x);int tmp=-inf;
    if (l1<=mid) tmp=max(tmp,query1(tree[x].left,l,mid,l1,r1));
    if (r1>mid) tmp=max(tmp,query1(tree[x].right,mid+1,r,l1,r1));return tmp;
}
int main(){
    freopen("bzoj3064.in","r",stdin);
    n=read();for (int i=1;i<=n;++i) a[i]=read();
    m=read();build(root,1,n);
    for (int i=1;i<=m;++i){
        char ch=gc();while(ch!='A'&&ch!='Q'&&ch!='P'&&ch!='C') ch=gc();
        if (ch=='Q') {
            int l=read(),r=read();printf("%d\n",query(root,1,n,l,r));
        }
        if (ch=='A'){
            int l=read(),r=read();printf("%d\n",query1(root,1,n,l,r));
        }
        if (ch=='P'){
            int l=read(),r=read(),v=read();insert1(root,1,n,l,r,v);
        }
        if (ch=='C'){
            int l=read(),r=read(),v=read();change(root,1,n,l,r,v);
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值