• UOJ #169. 【UR #11】元旦老人与数列 segment-tree-beats


    这道题好麻烦的.   

    把次小值和最小值一起更新,WA 了半天.           

    这道题采用的是势能分析的做法,并没有用到 CPU 监控那道题中的打标记法. 

    有时间再研究一下这几类线段树的异同. 

    code:   

    #include <cstdio> 
    #include <algorithm> 
    #include <cstring> 
    #include <cmath>     
    #define ll long long 
    #define N 500006     
    #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; 
    int nmin[N<<2],pmin[N<<2],se[N<<2];   
    int ptag_a[N<<2],ntag_a[N<<2],ptag_b[N<<2],ntag_b[N<<2];                    
    void pushup(int x) 
    {
        nmin[x]=min(nmin[lson],nmin[rson]);   
        pmin[x]=min(pmin[lson],pmin[rson]);      
        if(nmin[lson]<nmin[rson])  se[x]=min(se[lson],nmin[rson]);   
        if(nmin[rson]<nmin[lson])  se[x]=min(se[rson],nmin[lson]);  
        if(nmin[lson]==nmin[rson]) se[x]=min(se[lson],se[rson]);   
    }   
    // v1 表示历史最小                
    void mark_a(int x,int v1,int v2) 
    {               
        pmin[x]=min(pmin[x],nmin[x]+v1);        
        ptag_a[x]=min(ptag_a[x],ntag_a[x]+v1);     
        nmin[x]+=v2,ntag_a[x]+=v2;                       
    } 
    void mark_b(int x,int v1,int v2) 
    {
        ptag_b[x]=min(ptag_b[x],ntag_b[x]+v1);   
        ntag_b[x]+=v2;    
        if(se[x]!=inf) se[x]+=v2; 
    }
    void pushdown(int x) 
    {     
        int c=min(nmin[lson],nmin[rson]);     
        if(nmin[lson]==c) 
        {
            mark_a(lson,ptag_a[x],ntag_a[x]);       
            mark_b(lson,ptag_b[x],ntag_b[x]);  
        }   
        else 
        {
            mark_a(lson,ptag_b[x],ntag_b[x]);      
            mark_b(lson,ptag_b[x],ntag_b[x]);   
        }    
        if(nmin[rson]==c) 
        {
            mark_a(rson,ptag_a[x],ntag_a[x]);       
            mark_b(rson,ptag_b[x],ntag_b[x]);  
        }   
        else 
        {
            mark_a(rson,ptag_b[x],ntag_b[x]);      
            mark_b(rson,ptag_b[x],ntag_b[x]);   
        }            
        ptag_a[x]=ntag_a[x]=ptag_b[x]=ntag_b[x]=0;    
    }                 
    void addv(int l,int r,int x,int L,int R,int v) 
    {
        if(l>=L&&r<=R) 
        {
            mark_a(x,v,v),mark_b(x,v,v);   
            return; 
        } 
        pushdown(x); 
        int mid=(l+r)>>1;      
        if(L<=mid)  addv(l,mid,lson,L,R,v); 
        if(R>mid)   addv(mid+1,r,rson,L,R,v);     
        pushup(x); 
    }
    void getmax(int l,int r,int x,int L,int R,int v) 
    {   
        if(nmin[x]>=v)  return;   
        if(l>=L&&r<=R&&se[x]>v)  
        {   
            mark_a(x,v-nmin[x],v-nmin[x]);       
            return; 
        } 
        pushdown(x); 
        int mid=(l+r)>>1;  
        if(L<=mid)    getmax(l,mid,lson,L,R,v); 
        if(R>mid)     getmax(mid+1,r,rson,L,R,v);     
        pushup(x); 
    }
    int queryn(int l,int r,int x,int L,int R) 
    {
        if(l>=L&&r<=R) return nmin[x];    
        pushdown(x); 
        int mid=(l+r)>>1;    
        if(L<=mid&&R>mid) return min(queryn(l,mid,lson,L,R),queryn(mid+1,r,rson,L,R));  
        else if(L<=mid) return queryn(l,mid,lson,L,R);  
        else return queryn(mid+1,r,rson,L,R);    
    } 
    int queryp(int l,int r,int x,int L,int R) 
    {
        if(l>=L&&r<=R) return pmin[x];    
        pushdown(x); 
        int mid=(l+r)>>1;    
        if(L<=mid&&R>mid) return min(queryp(l,mid,lson,L,R),queryp(mid+1,r,rson,L,R));  
        else if(L<=mid) return queryp(l,mid,lson,L,R);  
        else return queryp(mid+1,r,rson,L,R);    
    } 
    void build(int l,int r,int x) 
    {
        if(l==r) 
        {
            scanf("%d",&nmin[x]),pmin[x]=nmin[x],se[x]=inf; 
            return;    
        }   
        int mid=(l+r)>>1;    
        build(l,mid,lson),build(mid+1,r,rson);   
        pushup(x);  
    }
    int main() 
    { 
        // setIO("input"); 
        int n,m;   
        scanf("%d%d",&n,&m),build(1,n,1);  
        for(int i=1;i<=m;++i) 
        {
            int op,l,r,z;  
            scanf("%d%d%d",&op,&l,&r); 
            if(op==1)  scanf("%d",&z),addv(1,n,1,l,r,z);   
            if(op==2)  scanf("%d",&z),getmax(1,n,1,l,r,z);   
            if(op==3)  printf("%d
    ",queryn(1,n,1,l,r)); 
            if(op==4)  printf("%d
    ",queryp(1,n,1,l,r));    
        }        
        return 0;
    }
    

      

  • 相关阅读:
    Jenkins参数化构建
    python笔记
    jenkins定时任务
    技巧:Vimdiff 使用
    clover如何使用UEFI引导和EFI驱动选择
    Broadcast BCM94322 用ubuntu修改ID
    MAC实现睡眠和休眠唤醒
    MAC的睡眠模式介绍
    linux 用dd命令读写引导区文件
    MAC下打开FTP服务
  • 原文地址:https://www.cnblogs.com/guangheli/p/12563582.html
Copyright © 2020-2023  润新知