zoukankan      html  css  js  c++  java
  • 楼房重建(线段树+单调栈)

    OvO

    • 线段树上维护一个单调栈,单点修改,查询(tr[1]).
    • 这个不用(pushdown),主要是难在(pushup)上。
    int Update(double M,int i,int l,int r){
        if(tr[i].Max<=M)return 0;
        if(a[l]>M)return tr[i].len;
        if(l==r)return a[l]>M;
        int mid=(l+r)>>1;
        if(tr[i<<1].Max<=M)return Update(M,i<<1|1,mid+1,r);
        else return tr[i].len-tr[i<<1].len+Update(M,i<<1,l,mid);
    }
    tr[i].len=tr[i<<1].len+Update(tr[i<<1].Max,i<<1|1,mid+1,r);
    

    因为对于一个更新来说,肯定是不能不要前半截的,也就是前面的不能选择式忽略。
    所以左儿子的(len)必须加上。然后去选择加上右儿子符合要求的长度。

    • (Update)里:
      如果右儿子中的最大值小于左儿子中的最大值,那就直接返回(0)就好。因为不可能有贡献了。
      如果右儿子的第一个就大于左儿子的最大值,那么右儿子的(len)值就全部满足条件了,所以直接返回(len)就好。
      如果这是个叶子节点的话,也是看值和左儿子最大值的关系。
      接下来设(s1)是右儿子的左儿子,(s2)是右儿子的右儿子。
      如果(s1.Max<=M),那么(s1)对答案已经做不了贡献了,直接返回(s2)的贡献即可。
      反之,则返回答案为从(s1)中找的符合要求的长度再加上右儿子的贡献即可。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn=1e5+1;
    int n,m;
    double a[maxn];
    struct E{double Max;int len;}tr[maxn<<2];
    int Update(double M,int i,int l,int r){
        if(tr[i].Max<=M)return 0;
        if(a[l]>M)return tr[i].len;
        if(l==r)return a[l]>M;
        int mid=(l+r)>>1;
        if(tr[i<<1].Max<=M)return Update(M,i<<1|1,mid+1,r);
        else return tr[i].len-tr[i<<1].len+Update(M,i<<1,l,mid);
    }
    void Change(int i,int l,int r,int pos,int k){
        if(l==r){
            tr[i].Max=(double)k/pos;
            tr[i].len=1;
            return;
        }int mid=(l+r)>>1;
        if(pos<=mid)Change(i<<1,l,mid,pos,k);
        else Change(i<<1|1,mid+1,r,pos,k);
        tr[i].Max=max(tr[i<<1].Max,tr[i<<1|1].Max);
        tr[i].len=tr[i<<1].len+Update(tr[i<<1].Max,i<<1|1,mid+1,r);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int k,pos;scanf("%d%d",&pos,&k);
            a[pos]=(double)k/pos;
            Change(1,1,n,pos,k);
            printf("%d
    ",tr[1].len);
        }
        return 0;
    }
    
  • 相关阅读:
    [QT][待解决问题]对话框ui载入卡顿问题
    [QT] Tab键切换焦点顺序
    [QT][问题记录]发布软件时遇到的问题
    [QT][转载] Qt信号和槽
    [QT][转载]Qt:使用C++还是QML
    [qt][问题记录] 无法定位程序输入点 _ZdaPvj 于动态链接库 libstdc++-6.dll
    [QT]安装中出现的问题(安装qt5.8,出现Could not start:"{0,3010,1603,5100} msiexec ...")
    [转载]Lwip之IP/MAC地址冲突检测
    转载:TCP连接的状态详解以及故障排查
    git push (第一次) (转)
  • 原文地址:https://www.cnblogs.com/13ZY/p/13805602.html
Copyright © 2011-2022 走看看