zoukankan      html  css  js  c++  java
  • 【bzoj5050】【bzoj九月月赛H】建造摩天楼

    讲个笑话,这个题很休闲的。

    大概是这样的,昨天看到这个题,第一眼星际把题目看反了然后感觉这是个傻逼题。

    后来发现不对,这个修改一次的影响是很多的,可能导致一个数突然可以被改,也可能导致一个数不能被改。

    大概就是一个不断拔高,最后拔得跟区间最大值一样高的过程。

    后来开始想做法,感觉是不是可以维护一下最小的深度差,然后这个以内直接加,超过了就重构?

    感觉似乎有点道理,写写写

    自己想又感觉这个不太靠谱,可能会重构上天,然后就删了。

    (flag++)

    然后问了栋老师,栋老师一眼星际(跟我下午一样),然后忙着写集训队作业去了。

    (天下神犇都神的相似,傻逼各有各的傻法)

    后来问了lxl,挂张图:

    他说的似乎有点道理,然而我没太弄懂他想表达什么

    于是GG看其他题目去了。。。。。。

    后来看了题解……

    mdzz这不是我下午想的那个吗……?

    然后想了下这个随机期望的复杂度,不太会,问了下栋老师,大概得到的结果是这样的:

    首先分类讨论。

    所以重构会在常数次,因此题解的复杂度是正确的~

    然后谈一下维护:

    由于变化会影响左右两边,所以维护一下左右两边的最小深度,每次在线段树上收集重构节点,大力计算就好。

    #include<bits/stdc++.h>
    #define lson (o<<1)
    #define rson (o<<1|1)
    const int N=100010;
    const int inf=2147483647;
    typedef long long ll;
    inline int min(int x,int y){return x<y?x:y;}
    using namespace std;
    int n,m,a[N],exis[N],exl[N],exr[N],cnt,q[N];
    ll sumv[N<<2];int addv[N<<2],minl[N<<2],minr[N<<2],size[N<<2];
    const int ch_top=4e7+3;
    typedef long long ll;
    char ch[ch_top],*now_r=ch-1,*now_w=ch-1;
    inline int read(){
        while(*++now_r<'0');
        register int x=*now_r-'0';
        while(*++now_r>='0')x=x*10+*now_r-'0';
        return x;
    }
    inline void write(ll x){
        static char st[20];static int top;
        while(st[++top]='0'+x%10,x/=10);
        while(*++now_w=st[top],--top);
        *++now_w='
    ';
    }
    inline void pushup(int o){
        minr[o]=min(minr[lson],minr[rson]);
        minl[o]=min(minl[lson],minl[rson]);
    }
    inline void puttag(int o,int v){
        sumv[o]+=v*size[o];addv[o]+=v;minl[o]-=v;minr[o]-=v;
    }
    inline void pushdown(int o){
        if(!addv[o])return;
        puttag(lson,addv[o]);puttag(rson,addv[o]);
        addv[o]=0;
    }
    inline void build(int o,int l,int r){
        if(l==r){
            sumv[o]=a[l];size[o]=exis[l];minl[o]=exl[l];minr[o]=exr[l];
            return;
        }
        int mid=(l+r)>>1;
        build(lson,l,mid);build(rson,mid+1,r);
        pushup(o);
        sumv[o]=sumv[lson]+sumv[rson];
        size[o]=size[lson]+size[rson];
    }
    inline void recalc(int o,int l,int r,int q){
        if(l==r){
            if(exis[l])a[l]+=addv[o];
            addv[o]=0;return;
        }
        pushdown(o);
        int mid=(l+r)>>1;
        if(q<=mid)recalc(lson,l,mid,q);else recalc(rson,mid+1,r,q);
    }
    inline ll querysum(int o,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return sumv[o];
        pushdown(o);
        int mid=(l+r)>>1;ll ans=0;
        if(ql<=mid)ans+=querysum(lson,l,mid,ql,qr);
        if(qr>mid)ans+=querysum(rson,mid+1,r,ql,qr);
        return ans;
    }
    inline void change(int o,int l,int r,int ql,int qr){
        if(ql<=l&&r<=qr)return void(puttag(o,1));
        pushdown(o);int mid=(l+r)>>1;
        if(ql<=mid)change(lson,l,mid,ql,qr);
        if(qr>mid)change(rson,mid+1,r,ql,qr);
        pushup(o);
        sumv[o]=sumv[lson]+sumv[rson];
    }
    inline void recexi(int o,int l,int r,int q){
        if(l==r){
            size[o]=exis[l];minl[o]=exl[l];minr[o]=exr[l];
            return;
        }
        pushdown(o);int mid=(l+r)>>1;
        if(q<=mid)recexi(lson,l,mid,q);else recexi(rson,mid+1,r,q);
        pushup(o);
        size[o]=size[lson]+size[rson];
    }
    inline void recml(int o,int l,int r,int q,int v){
        if(l==r){minl[o]=v;return;}
        pushdown(o);int mid=(l+r)>>1;
        if(q<=mid)recml(lson,l,mid,q,v);else recml(rson,mid+1,r,q,v);
        minl[o]=min(minl[lson],minl[rson]);
    }
    inline void recmr(int o,int l,int r,int q,int v){
        if(l==r){minr[o]=v;return;}
        pushdown(o);int mid=(l+r)>>1;
        if(q<=mid)recmr(lson,l,mid,q,v);else recmr(rson,mid+1,r,q,v);
        minr[o]=min(minr[lson],minr[rson]);
    }
    inline void dfs(int o,int l,int r){
        if(minl[o]>0&&minr[o]>=0)return;
        if(l==r){
            if(minl[o]<=0&&q[cnt]!=l)q[++cnt]=l;
            if(minr[o]<0)q[++cnt]=l+1;
            return;
        }
        pushdown(o);int mid=(l+r)>>1;
        dfs(lson,l,mid);dfs(rson,mid+1,r);
    }
    inline bool flag(int i){return a[i-1]>a[i];}
    inline int calcl(int i){return exis[i]&&!exis[i-1]?a[i-1]-a[i]:inf;}
    inline int calcr(int i){return exis[i]&&!exis[i+1]?a[i+1]-a[i]:inf;}
    inline void calcexl(int i){if(i<1||i>n)return;recml(1,0,n+1,i,calcl(i));}
    inline void calcexr(int i){if(i<1||i>n)return;recmr(1,0,n+1,i,calcr(i));}
    inline void get(int i){if(i<1||i>n)return;recalc(1,0,n+1,i);}
    inline void qwq(int i){
        if(i<1||i>n)return;get(i);get(i-1);get(i+1);exis[i]=flag(i);exl[i]=calcl(i);exr[i]=calcr(i);
        recexi(1,0,n+1,i);calcexl(i+1);calcexr(i-1);
    }
    int main(){
        fread(ch,1,ch_top,stdin);
        n=read();m=read();
        a[0]=exl[0]=exr[0]=inf;a[n+1]=exl[n+1]=exr[n+1]=inf;
        for(int i=1;i<=n;i++)a[i]=read(),exis[i]=flag(i);
        for(int i=1;i<=n;i++)exl[i]=calcl(i),exr[i]=calcr(i);
        build(1,0,n+1);
        while(m--){
            int opt=read(),x=read(),y=read();
            if(opt==1){
                cnt=0;change(1,0,n+1,x,y);dfs(1,0,n+1);
                for(int i=1;i<=cnt;i++)qwq(q[i]);
                qwq(x);qwq(y+1);
            }
            else{
                write(querysum(1,0,n+1,x,y));
            }
        }
        fwrite(ch,1,now_w-ch,stdout);
    }
  • 相关阅读:
    面向对象基本原则
    策略模式
    简单工厂模式
    高内聚、低耦合
    UML在代码中的展现
    使用commons-csv简单读写CSV文件
    java反射机制
    SrpingDruid数据源加密数据库密码
    markdown学习经验
    Vue.js学习笔记
  • 原文地址:https://www.cnblogs.com/zcysky/p/7580231.html
Copyright © 2011-2022 走看看