zoukankan      html  css  js  c++  java
  • 解题:洛谷4314 CPU监控

    题面

    线段树·二重标记(什么鬼

    用(a,b)标记表示先执行+a操作,然后对b取max,维护历史/当前最大值和历史/当前标记。然后我们发现区间加$x$就是$(x,-inf)$,区间赋$x$就是$(-inf,x)$。标记有两种更新,一种是和当前的标记合并,一种是更新历史标记。

    把一个标记tag合并进当前标记ntag,显然新标记即

    $(ntag.a+tag.a,max(ntag.b+tag.a,tag.b))$

    把历史标记htag用一个标记tag更新更简单,其实就是对应取max

    那么就可以做了:修改标记即先把当前标记和要加的标记合并,然后更新历史标记;修改最大值将当前最大值按标记意思改,然后历史最大值和当前最大值取max。下放标记类似

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=100005,inf=0x3f3f3f3f;
     6 struct a
     7 {
     8     int ad,mx;
     9     void init()
    10     {
    11         ad=0,mx=-inf;
    12     }
    13 }hist[4*N],nowt[4*N];
    14 a operator + (a x,a y)
    15 {
    16     return (a){max(-inf,x.ad+y.ad),max(x.mx+y.ad,y.mx)};
    17 }
    18 a operator ^ (a x,a y)
    19 {
    20     return (a){max(x.ad,y.ad),max(x.mx,y.mx)};
    21 }
    22 int seq[N],hmax[4*N],nmax[4*N];
    23 int n,m,t1,t2,t3; char str[10];
    24 void Pushup(int nde)
    25 {
    26     int ls=2*nde,rs=2*nde+1;
    27     hmax[nde]=max(hmax[ls],hmax[rs]);
    28     nmax[nde]=max(nmax[ls],nmax[rs]);
    29 }
    30 void Apply(int nde,int tsk)
    31 {
    32     hist[nde]=hist[nde]^(nowt[nde]+hist[tsk]); nowt[nde]=nowt[nde]+nowt[tsk];
    33     hmax[nde]=max(hmax[nde],max(nmax[nde]+hist[tsk].ad,hist[tsk].mx)); 
    34     nmax[nde]=max(nmax[nde]+nowt[tsk].ad,nowt[tsk].mx); 
    35 }
    36 void Release(int nde)
    37 {
    38     int ls=2*nde,rs=2*nde+1;
    39     Apply(ls,nde),Apply(rs,nde);
    40     hist[nde].init(),nowt[nde].init();
    41 }
    42 void Create(int nde,int l,int r)
    43 {
    44     hist[nde].init(),nowt[nde].init();
    45     if(l==r)
    46         hmax[nde]=nmax[nde]=seq[l];
    47     else
    48     {
    49         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1;
    50         Create(ls,l,mid),Create(rs,mid+1,r);
    51         Pushup(nde);
    52     }
    53 }
    54 void Change(int nde,int l,int r,int nl,int nr,a tsk)
    55 {
    56     if(l>nr||r<nl)
    57         return ;
    58     else if(l>=nl&&r<=nr)
    59     {
    60         hist[nde]=hist[nde]^(nowt[nde]+tsk); nowt[nde]=nowt[nde]+tsk;
    61         hmax[nde]=max(hmax[nde],max(nmax[nde]+tsk.ad,tsk.mx)); 
    62         nmax[nde]=max(nmax[nde]+tsk.ad,tsk.mx);
    63     }
    64     else
    65     {
    66         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde);
    67         Change(ls,l,mid,nl,nr,tsk),Change(rs,mid+1,r,nl,nr,tsk);
    68         Pushup(nde);
    69     }
    70 }
    71 int Query(int nde,int l,int r,int nl,int nr,int typ)
    72 {
    73     if(l>nr||r<nl)
    74         return -inf;
    75     else if(l>=nl&&r<=nr)
    76         return typ?nmax[nde]:hmax[nde];
    77     else
    78     {
    79         int mid=(l+r)/2,ls=2*nde,rs=2*nde+1; Release(nde);
    80         return max(Query(ls,l,mid,nl,nr,typ),Query(rs,mid+1,r,nl,nr,typ));
    81     }
    82 }
    83 int main()
    84 {
    85     scanf("%d",&n);
    86     for(int i=1;i<=n;i++)
    87         scanf("%d",&seq[i]);
    88     Create(1,1,n),scanf("%d",&m);
    89     for(int i=1;i<=m;i++)
    90     {
    91         scanf("%s%d%d",str,&t1,&t2);
    92         if(str[0]=='Q') printf("%d
    ",Query(1,1,n,t1,t2,1));
    93         else if(str[0]=='A') printf("%d
    ",Query(1,1,n,t1,t2,0));
    94         else if(str[0]=='P') scanf("%d",&t3),Change(1,1,n,t1,t2,(a){t3,-inf});
    95         else if(str[0]=='C') scanf("%d",&t3),Change(1,1,n,t1,t2,(a){-inf,t3});
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    vs2015解决fopen、fscanf 要求替换为fopen_s、fscanf_s的办法
    ThinkPHP5.1的公共函数
    Linux禁止ping
    2019.10.17 上科大虞晶怡教授
    Minimax极大极小算法、Alpha-Beta Pruning剪枝算法
    Apache24服务无法启动,发生服务特定错误1.
    LaTeX小白安装超详细步骤(WIndows系统)||相信我看这个安装就够啦!
    Java中Comparator比较器的使用
    当我看到别人二战想法,退缩的时候,我的感受
    2019.12.3 学英语的心得;学习学习
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10181265.html
Copyright © 2011-2022 走看看