• BZOJ 3064: Tyvj 1518 CPU监控 线段树维护历史最值


    $(x,y)$ 表示加完 $x$,再对 $y$ 取 max 的操作.  

    那么有 $(a,b)+(c,d)=(a+c,max(b+c,d))$                         

    然后对于两个标记取 max 的话是 $(max(a,c),max(b,d))$  

    知道这些之后就好做了.  

    一定要注意:先更新历史最值标记,然后再更新当前最值(因为历史最值标记需要用到当前最值标记)  

    code:   

    #include <cstdio> 
    #include <algorithm> 
    #include <cstring>    
    #define N 100006   
    #define lson x<<1  
    #define rson x<<1|1  
    #define inf 0x3f3f3f3f    
    #define I(s) freopen(s".in","r",stdin) 
    #define O(s) freopen(s".out","w",stdout)   
    #define setIO(s) I(s),O(s) 
    using namespace std;           
    struct data 
    {      
        int x,y;  
        data(int a=0,int b=-inf) { x=a,y=b; }         
        data operator+(const data &a)const { return data(max(-inf,x+a.x),max(y+a.x,a.y)); }   
        data operator*(const data &a)const { return data(max(x,a.x),max(y,a.y)); }        
    }ptag[N<<2],ntag[N<<2];     
    int n;                  
    int pmax[N<<2],nmax[N<<2];             
    void pushup(int x) 
    {
        pmax[x]=max(pmax[lson],pmax[rson]);  
        nmax[x]=max(nmax[lson],nmax[rson]);  
    }    
    void build(int l,int r,int x) 
    {
        ptag[x]=ntag[x]=data();    
        if(l==r) 
        {   
            scanf("%d",&nmax[x]),pmax[x]=nmax[x]; 
            return;   
        } 
        int mid=(l+r)>>1;   
        build(l,mid,lson),build(mid+1,r,rson);   
        pushup(x);  
    }   
    //  对于历史最大值           
    void mark_n(int x,data v) 
    {
        ntag[x]=ntag[x]+v;     
        nmax[x]=max(nmax[x]+v.x,v.y);        
    }
    void mark_p(int x,data v) 
    {           
        ptag[x]=ptag[x]*(ntag[x]+v);      
        pmax[x]=max(pmax[x],max(nmax[x]+v.x,v.y));       
    }       
    void pushdown(int x) 
    { 
        mark_p(lson,ptag[x]); 
        mark_n(lson,ntag[x]);      
        mark_p(rson,ptag[x]);        
        mark_n(rson,ntag[x]);
        ntag[x]=ptag[x]=data();    
    }
    void update(int l,int r,int x,int L,int R,data v) 
    {  
        if(l>=L&&r<=R) 
        {          
            mark_p(x,v); 
            mark_n(x,v);   
            return; 
        }  
        pushdown(x); 
        int mid=(l+r)>>1;     
        if(L<=mid) update(l,mid,lson,L,R,v); 
        if(R>mid)  update(mid+1,r,rson,L,R,v);   
        pushup(x); 
    }  
    int query(int l,int r,int x,int L,int R,int o) 
    {
        if(l>=L&&r<=R) return o?nmax[x]:pmax[x];     
        pushdown(x); 
        int mid=(l+r)>>1,re=-inf;      
        if(L<=mid)  re=max(re,query(l,mid,lson,L,R,o));  
        if(R>mid)   re=max(re,query(mid+1,r,rson,L,R,o)); 
        return re;  
    }
    int main() 
    { 
        // setIO("input");    
        int m; 
        scanf("%d",&n);         
        build(1,n,1);   
        scanf("%d",&m);   
        for(int i=1;i<=m;++i) 
        {
            char opt[2];   
            int l,r,z; 
            scanf("%s%d%d",opt,&l,&r); 
            if(opt[0]=='Q')  printf("%d
    ",query(1,n,1,l,r,1)); 
            if(opt[0]=='A')  printf("%d
    ",query(1,n,1,l,r,0));   
            if(opt[0]=='P')  scanf("%d",&z),update(1,n,1,l,r,data(z,-inf));
            if(opt[0]=='C')  scanf("%d",&z),update(1,n,1,l,r,data(-inf,z));  
        }
        return 0; 
    }
    

      

  • 相关阅读:
    squid开多端口代理的心得
    用ssh跑pppd(最简单的linuxvpn)
    Asterisk1.2编译与安装
    E1 CE1 PRI BRI T1 的区别
    asterisk卡常见问题(收集整理)
    CCProxy+Eborder开透明代理详细设置(附图文)
    iptables+NAT+squid 透明代理上网实现方案
    asterisk积累命令
    MySQL Cluster的常见问题
    如何配置Silverlight4开发环境
  • 原文地址:https://www.cnblogs.com/guangheli/p/12561423.html
Copyright © 2020-2023  润新知