• [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
  • 相关阅读:
    sshd服务防止暴力破解
    使用秘钥ssh登录远程服务器
    SSH配置文件详解
    WinForm、wpf、silverlight三者关系
    silverlight 和winform的结合使用
    IIS在W7下使用
    c#多线程
    Silverlight的Socket通信
    wcf和webservice区别
    aspx向silverlight传值
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15350201.html
Copyright © 2020-2023  润新知