zoukankan      html  css  js  c++  java
  • BZOJ_2957_楼房重建_线段树

    BZOJ_2957_楼房重建_线段树

    Description

      小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。
      为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。
      施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi(高度可以比原来大---修建,也可以比原来小---拆除,甚至可以保持不变---建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?

    Input

      第一行两个正整数N,M
      接下来M行,每行两个正整数Xi,Yi

    Output


      M行,第i行一个整数表示第i天过后小A能看到的楼房有多少栋

    Sample Input


    3 4
    2 4
    3 6
    1 1000000000
    1 1

    Sample Output


    1
    1
    1
    2
    数据约定
      对于所有的数据1<=Xi<=N,1<=Yi<=10^9
    N,M<=100000

    线段树好题,但是我总结不出来任何套路....
    决定用线段树维护就多想想维护哪些信息、怎么上传之类的。
    先把每个楼房转换成斜率,这样每次我们就是求一个强制上升的子序列有多长。
    考虑线段树维护t[p]表示这个节点在只考虑节点对应区间时的答案,mx[p]表示区间最大的斜率。
    查询没啥问题。
    只需要解决修改时的pushup问题了。
    首先左子树的t肯定要累加答案,然后递归右子树。
    递归右子树的过程相当于只考虑斜率大于mx[ls]那部分的答案。
    同样考虑左子树和右子树。
    如果要查的斜率K大于mx[ls]则递归右子树即可。
    否则需要递归左子树,此时右子树对应的答案我们已经求过了。
    因为K小于等于mx[ls],考虑完左子树之后最大值会变成mx[ls],答案和只考虑左子树的情况下,右子树的答案是一样的,就是t[p]-t[ls]。
    每次pushup复杂度O(logn)。
     
    代码:
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    #define N 100050
    #define ls p<<1
    #define rs p<<1|1
    typedef double f2;
    int t[N<<2],n,m;
    f2 mx[N<<2];
    int calc(int l,int r,f2 v,int p) {
        if(l==r) return mx[p]>v;
        int mid=(l+r)>>1;
        if(mx[ls]<=v) return calc(mid+1,r,v,rs);
        else return calc(l,mid,v,ls)+t[p]-t[ls];
    }
    void update(int l,int r,int x,f2 v,int p) {
        if(l==r) {
            t[p]=1; mx[p]=v; return ;
        }
        int mid=(l+r)>>1;
        if(x<=mid) update(l,mid,x,v,ls);
        else update(mid+1,r,x,v,rs);
        mx[p]=max(mx[ls],mx[rs]);
        t[p]=t[ls]+calc(mid+1,r,mx[ls],rs);
    }
    int main() {
        scanf("%d%d",&n,&m);
        int i; int x,y;
        for(i=1;i<=m;i++) {
            scanf("%d%d",&x,&y); update(1,n,x,f2(y)/x,1);
            printf("%d
    ",t[1]);
        }
    }
    
  • 相关阅读:
    Jmeter之http性能测试实战 非GUI模式压测 NON-GUI模式 结果解析TPS——干货(十一)
    UI Recorder 自动化测试 回归原理(九)
    UI Recorder 自动化测试 录制原理(八)
    UI Recorder 自动化测试 整体架构(七)
    UI Recorder 自动化测试 配置项(六)
    UI Recorder 自动化测试 工具栏使用(五)
    UI Recorder 自动化测试 回归测试(四)
    UI Recorder 自动化测试 录制(三)
    UI Recorder 自动化测试工具安装问题疑难杂症解决(二)
    UI Recorder 自动化测试安装教程(一)
  • 原文地址:https://www.cnblogs.com/suika/p/9464045.html
Copyright © 2011-2022 走看看