码迷,mamicode.com
首页 > 其他好文 > 详细

[bzoj3064] [Tyvj 1518] CPU监控

时间:2019-01-05 18:21:56      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:tyvj   code   const   正整数   表示   做什么   namespace   char   clu   

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

对于每个询问,输出一行一个整数回答。

Solution

论文题就是强大QAQ

考虑把区间覆盖转化成区间取\(\max\),标记记成二元组\((x,y)\),表示先区间加上\(x\),再对\(y\)\(\max\),也就是\(a_i=\max(a_i+x,y)\)

那么区间加标记就是\((x,-\infty)\),区间覆盖就是\((-\infty,x)\)

然后对于每个点记两个标记\(now\)\(history\),表示当前标记和历史最大标记。

那么对于当前标记,将\((c,d)\)\((a,b)\)上合并,显然结果是\((a+c,\max(b+c,d))\)

对于历史最大标记,标记\((a,b)\)可以看成是一个形如\(y=\max(x+a,b)\)的函数,显然这是个分段函数,第一段是\(y=b\),第二段是\(y=x+a\),两个标记合并对于每个\(x\)都是要取最大值,所以取函数最上面那一段,标记\((a,b)\)\((c,d)\)合并的结果就是\((\max(a,c),\max(b,d))\)

然后具体看代码吧,(我能说我因为fread挂了而T了一版吗QAQ)

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;

namespace fast_IO {
    template <typename T> inline void read(T &x) {
        x=0;T f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    template <typename T,typename... Args> inline void read(T& x,Args& ...args) {
        read(x),read(args...);
    }

    char buf2[1<<21],a[80];int p,p3=-1;

    inline void flush() {fwrite(buf2,1,p3+1,stdout),p3=-1;}
    template <typename T> inline void write(T x) {
        if(p3>(1<<20)) flush();
        if(x<0) buf2[++p3]='-',x=-x;
        do {a[++p]=x%10+48;} while(x/=10);
        do {buf2[++p3]=a[p];} while(--p);
        buf2[++p3]='\n';
    }
    template <typename T,typename... Args> inline void write(T x,Args ...args) {
        write(x),write(args...);
    }
}

using fast_IO :: read;
using fast_IO :: write;
using fast_IO :: flush;

const int maxn = 1e5+10;
const int inf = 0x3f3f3f3f;

int n,m,val[maxn];
char s[10];

#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1)

struct Segment_Tree {
    int hmax[maxn<<2],nmax[maxn<<2];
    struct tag {
        int add,mx;
        inline void init() {add=0,mx=-inf;}
        inline tag operator + (const tag &rhs) const {return (tag){max(-inf,add+rhs.add),max(mx+rhs.add,rhs.mx)};}
        inline tag operator * (const tag &rhs) const {return (tag){max(add,rhs.add),max(mx,rhs.mx)};}
    }nlazy[maxn<<2],hlazy[maxn<<2];
    inline void update(int p) {
        hmax[p]=max(hmax[ls],hmax[rs]);
        nmax[p]=max(nmax[ls],nmax[rs]);
    }
    inline void push_tag(int p,tag now,tag history) {
        hlazy[p]=hlazy[p]*(nlazy[p]+history);
        nlazy[p]=nlazy[p]+now;
        hmax[p]=max(hmax[p],max(nmax[p]+history.add,history.mx));
        nmax[p]=max(nmax[p]+now.add,now.mx);
    }
    inline void pushdown(int p) {
        push_tag(ls,nlazy[p],hlazy[p]);
        push_tag(rs,nlazy[p],hlazy[p]);
        nlazy[p].init(),hlazy[p].init();
    }
    void modify(int p,int l,int r,int x,int y,int add,int mx) {
        if(x<=l&&r<=y) return push_tag(p,(tag){add,mx},(tag){add,mx}),void();
        pushdown(p);
        if(x<=mid) modify(ls,l,mid,x,y,add,mx);
        if(y>mid) modify(rs,mid+1,r,x,y,add,mx);
        update(p);
    }
    int query_hmax(int p,int l,int r,int x,int y) {
        if(x<=l&&r<=y) return hmax[p];
        int ans=-inf;pushdown(p);
        if(x<=mid) ans=max(ans,query_hmax(ls,l,mid,x,y));
        if(y>mid) ans=max(ans,query_hmax(rs,mid+1,r,x,y));
        return ans;     
    }
    int query_nmax(int p,int l,int r,int x,int y) {
        if(x<=l&&r<=y) return nmax[p];
        int ans=-inf;pushdown(p);
        if(x<=mid) ans=max(ans,query_nmax(ls,l,mid,x,y));
        if(y>mid) ans=max(ans,query_nmax(rs,mid+1,r,x,y));
        return ans;     
    }
    void build(int p,int l,int r) {
        hlazy[p].init(),nlazy[p].init();
        if(l==r) return hmax[p]=nmax[p]=val[l],void();
        build(ls,l,mid),build(rs,mid+1,r),update(p);
    }
}SGT;

#undef ls
#undef rs
#undef mid

int main() {
    read(n);
    for(int i=1;i<=n;i++) read(val[i]);
    SGT.build(1,1,n);
    read(m);
    for(int i=1;i<=m;i++) {
        scanf("%s",s+1);int x,y,z;read(x,y);
        if(s[1]=='Q') write(SGT.query_nmax(1,1,n,x,y));
        else if(s[1]=='A') write(SGT.query_hmax(1,1,n,x,y));
        else if(s[1]=='P') read(z),SGT.modify(1,1,n,x,y,z,-inf);
        else read(z),SGT.modify(1,1,n,x,y,-inf,z);
    }
    flush();
    return 0;
}

[bzoj3064] [Tyvj 1518] CPU监控

标签:tyvj   code   const   正整数   表示   做什么   namespace   char   clu   

原文地址:https://www.cnblogs.com/hbyer/p/10225233.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!