• 【UOJ#169】元旦老人与数列


    论文题。

    考虑到这题的维护和区间操作是反向的,也就是说无法像V那题快速的合并标记。

    我们知道,一个区间的最小值和其他值是可以分开来维护的,因为如果一个区间被整体覆盖,那么最小值始终是最小值。

    对于被覆盖一半的区间,讨论一下即可。

    对于每个最小值和次小值记录前缀最小值,当前/历史最小值,当到达合法区间的时候:

    如果区间最小值>x,直接退出。

    如果minv[o]<x<semn[o],那么更新当前的次小值

    反之继续向下。

    #include<bits/stdc++.h>
    const int inf=2e9+7;
    const int N=500005;
    using namespace std;
    inline int read(){
        int f=1,x=0;char ch;
        do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
        do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
        return f*x;
    }
    int n,m;
    struct Segment_Tree_Beats{
    #define lson (o<<1)
    #define rson (o<<1|1)
        int his[N<<2],pra[N<<2],prb[N<<2],a[N<<2],b[N<<2],minv[N<<2],semn[N<<2];
        inline void pushup(int o){
            if(minv[lson]==minv[rson])minv[o]=minv[lson],semn[o]=min(semn[lson],semn[rson]);
            else if(minv[lson]<minv[rson]){minv[o]=minv[lson];semn[o]=min(semn[lson],minv[rson]);}
            else{minv[o]=minv[rson];semn[o]=min(semn[rson],minv[lson]);}
            his[o]=min(his[lson],his[rson]);
        }
        inline void puttag(int o,int v){
            his[o]=min(his[o],minv[o]+v);
            a[o]+=v;b[o]+=v;minv[o]+=v;semn[o]+=v;semn[o]=min(semn[o],inf);
            pra[o]=min(pra[o],a[o]);
            prb[o]=min(prb[o],b[o]);
        }
        inline void plus(int o,int ax,int pa,int bx,int pb){
            his[o]=min(his[o],minv[o]+pa);
            pra[o]=min(pra[o],pa+a[o]);
            prb[o]=min(prb[o],pb+b[o]);
            a[o]+=ax;b[o]+=bx;minv[o]+=ax;semn[o]+=bx;semn[o]=min(semn[o],inf);
        }
        inline void pushdown(int o){
            int mmmm=min(minv[lson],minv[rson]);
            if(minv[lson]==mmmm)plus(lson,a[o],pra[o],b[o],prb[o]);else plus(lson,b[o],prb[o],b[o],prb[o]);
            if(minv[rson]==mmmm)plus(rson,a[o],pra[o],b[o],prb[o]);else plus(rson,b[o],prb[o],b[o],prb[o]);
            a[o]=b[o]=pra[o]=prb[o]=0;
        }
        inline void build(int o,int l,int r){
            if(l==r){
                minv[o]=read();his[o]=minv[o];semn[o]=inf;
                return;
            }
            int mid=(l+r)>>1;
            build(lson,l,mid);build(rson,mid+1,r);
            pushup(o);
        }
        inline void optadd(int o,int l,int r,int ql,int qr,int v){
            if(ql<=l&&r<=qr){puttag(o,v);return;}
            int mid=(l+r)>>1;pushdown(o);
            if(ql<=mid)optadd(lson,l,mid,ql,qr,v);
            if(qr>mid)optadd(rson,mid+1,r,ql,qr,v);
            pushup(o);
        }
        inline void dfs(int o,int l,int r,int v){
            if(minv[o]>=v)return;
            if(semn[o]>v){
                v-=minv[o];his[o]=min(his[o],minv[o]+v);
                pra[o]=min(pra[o],a[o]+v);
                a[o]+=v;minv[o]+=v;return;
            }
            int mid=(l+r)>>1;pushdown(o);
            dfs(lson,l,mid,v);dfs(rson,mid+1,r,v);
            pushup(o);
        }
        inline void change(int o,int l,int r,int ql,int qr,int v){
            if(ql<=l&&r<=qr){dfs(o,l,r,v);return;}
            int mid=(l+r)>>1;pushdown(o);
            if(ql<=mid)change(lson,l,mid,ql,qr,v);
            if(qr>mid)change(rson,mid+1,r,ql,qr,v);
            pushup(o);
        }
        inline int querynow(int o,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return minv[o];
            int mid=(l+r)>>1,ans=inf;pushdown(o);
            if(ql<=mid)ans=min(ans,querynow(lson,l,mid,ql,qr));
            if(qr>mid)ans=min(ans,querynow(rson,mid+1,r,ql,qr));
            return ans;
        }
        inline int queryhis(int o,int l,int r,int ql,int qr){
            if(ql<=l&&r<=qr)return his[o];
            int mid=(l+r)>>1,ans=inf;pushdown(o);
            if(ql<=mid)ans=min(ans,queryhis(lson,l,mid,ql,qr));
            if(qr>mid)ans=min(ans,queryhis(rson,mid+1,r,ql,qr));
            return ans;
        }
    }T;
    int main(){
        n=read();m=read();
        T.build(1,1,n);
        while(m--){
            int opt=read(),l=read(),r=read();
            if(opt==1){int x=read();T.optadd(1,1,n,l,r,x);}
            if(opt==2){int x=read();T.change(1,1,n,l,r,x);}
            if(opt==3)printf("%d
    ",T.querynow(1,1,n,l,r));
            if(opt==4)printf("%d
    ",T.queryhis(1,1,n,l,r));
        }
    }
  • 相关阅读:
    Android APK安装过程介绍
    Android Linux自带iptables配置IP访问规则
    海康视频监控---Demo
    Go之获取Windows下文件是否隐藏
    Go之go与channel组合使用
    Go并发编程(四)
    Go错误处理(二)
    Go面向对象(三)
    判断两端日期是否重合
    Sql分页存储过程
  • 原文地址:https://www.cnblogs.com/zcysky/p/7392452.html
Copyright © 2020-2023  润新知