zoukankan      html  css  js  c++  java
  • [bzoj3064]CPU监控

    记$a_{i}$为时刻$i$当前cpu使用率,$b_{i}$为$a_{i}$的历史最大值

    不难发现,问题即要支持:对$a_{i}$区间赋值和区间加;查询$a_{i}$和$b_{i}$的区间最大值

    在线段树的节点上维护$max a,b$和一个操作序列(类似懒标记),序列中的元素为操作(赋值或加),并要求其依次执行这些操作,执行方式即令
    $$
    egin{cases}max a=x,max b=max(max b,max a)&(覆盖操作)\max a=max a+x,max b=max(max b,max a)&(加操作)end{cases}
    $$

    (注意$max b$中的$max a$均是操作后的)
    但这样在下传标记时,即将父亲的操作序列接在儿子后面,显然无法保证复杂度

    分析操作序列的实际影响,即令$max a$为最后一次赋值操作+其之后的加操作的和、$max b=max(max b,$每一次赋值操作+其之后加操作的最大前缀和$)$

    由此,不难发现维护以下信息即可支持执行和合并(拼接):

    1.加操作的极长前缀和、最大前缀和(指不包含赋值操作的前缀,为空则均记为0)

    2.是否存在赋值操作

    3.最后一次赋值操作后加操作的和、最大前缀和(包括该次赋值操作,若没有赋值操作则记为0和$-infty$)

    4.每一次赋值操作+其之后加操作的最大前缀和的最大值(若没有赋值操作则记为$-infty$)

    具体合并方式可以根据定义得到或参考代码,这里省略

    时间复杂度为$o(mlog n)$,可以通过

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 100005
     4 #define L (k<<1)
     5 #define R (L+1)
     6 #define mid (l+r>>1)
     7 struct Data{
     8     int s1,mx1,p,s2,mx2,Mx;
     9 }tag[N<<2];
    10 int n,m,x,y,z,a[N],mx_a[N<<2],mx_b[N<<2];
    11 char s[11];
    12 void upd(int k,Data x){
    13     mx_b[k]=max(mx_b[k],max(mx_a[k]+x.mx1,x.Mx));
    14     if (!x.p)mx_a[k]+=x.s1;
    15     else mx_a[k]=x.s2;
    16     if (!tag[k].p){
    17         tag[k].mx1=max(tag[k].mx1,tag[k].s1+x.mx1);
    18         tag[k].s1+=x.s1;
    19     }
    20     else{
    21         tag[k].mx2=max(tag[k].mx2,tag[k].s2+x.mx1);
    22         tag[k].Mx=max(tag[k].Mx,tag[k].s2+x.mx1);
    23         tag[k].s2+=x.s1;
    24     }
    25     if (x.p){
    26         tag[k].p=1,tag[k].s2=x.s2,tag[k].mx2=x.mx2;
    27         tag[k].Mx=max(tag[k].Mx,x.Mx);
    28     }
    29 }
    30 void up(int k){
    31     mx_a[k]=max(mx_a[L],mx_a[R]);
    32     mx_b[k]=max(mx_b[L],mx_b[R]);
    33 }
    34 void down(int k){
    35     upd(L,tag[k]);
    36     upd(R,tag[k]);
    37     tag[k]=Data{0,0,0,0,INT_MIN,INT_MIN};
    38 }
    39 void build(int k,int l,int r){
    40     tag[k]=Data{0,0,0,0,INT_MIN,INT_MIN};
    41     if (l==r){
    42         mx_a[k]=mx_b[k]=a[l];
    43         return;
    44     } 
    45     build(L,l,mid);
    46     build(R,mid+1,r);
    47     up(k);
    48 }
    49 void update(int k,int l,int r,int x,int y,Data z){
    50     if ((l>y)||(x>r))return;
    51     if ((x<=l)&&(r<=y)){
    52         upd(k,z);
    53         return;
    54     }
    55     down(k);
    56     update(L,l,mid,x,y,z);
    57     update(R,mid+1,r,x,y,z);
    58     up(k);
    59 }
    60 int query_a(int k,int l,int r,int x,int y){
    61     if ((l>y)||(x>r))return INT_MIN;
    62     if ((x<=l)&&(r<=y))return mx_a[k];
    63     down(k);
    64     return max(query_a(L,l,mid,x,y),query_a(R,mid+1,r,x,y));
    65 }
    66 int query_b(int k,int l,int r,int x,int y){
    67     if ((l>y)||(x>r))return INT_MIN;
    68     if ((x<=l)&&(r<=y))return mx_b[k];
    69     down(k);
    70     return max(query_b(L,l,mid,x,y),query_b(R,mid+1,r,x,y));
    71 }
    72 int main(){
    73     scanf("%d",&n);
    74     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    75     build(1,1,n);
    76     scanf("%d",&m);
    77     for(int i=1;i<=m;i++){
    78         scanf("%s%d%d",s,&x,&y);
    79         if (s[0]=='Q')printf("%d
    ",query_a(1,1,n,x,y));
    80         if (s[0]=='A')printf("%d
    ",query_b(1,1,n,x,y));
    81         if (s[0]=='P'){
    82             scanf("%d",&z);
    83             update(1,1,n,x,y,Data{z,max(z,0),0,0,0,INT_MIN});
    84         }
    85         if (s[0]=='C'){
    86             scanf("%d",&z);
    87             update(1,1,n,x,y,Data{0,0,1,z,z,z});
    88         }
    89     }
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    Data Base mysql备份与恢复
    java 乱码问题解决方案
    【知识强化】第二章 物理层 2.1 通信基础
    【知识强化】第二章 进程管理 2.2 处理机调度
    【知识强化】第二章 进程管理 2.1 进程与线程
    【知识强化】第一章 操作系统概述 1.3 操作系统的运行环境
    【知识强化】第一章 网络体系结构 1.1 数据结构的基本概念
    【知识强化】第一章 网络体系结构 1.2 计算机网络体系结构与参考模型
    【知识强化】第一章 网络体系结构 1.1 计算机网络概述
    【知识强化】第一章 操作系统概述 1.1 操作系统的基本概念
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15350201.html
Copyright © 2011-2022 走看看