zoukankan      html  css  js  c++  java
  • BZOJ 2957: 楼房重建

    题目描述

    /*
    思路非常巧妙的一道题 
    不难看出线段树维护的是区间内每个点与原点连线的斜率的最大值 
    考虑合并区间时怎么合并答案 
    左区间一定会被看到,右区间能被看到的一定大于左区间的最大值 
    所以可以查询右区间中大于左区间最大值的数的个数来向上合并 
    每次修改的复杂度为log^2n 
    */
    #include<complex>
    #include<cstdio>
    using namespace std;
    const int N=1e5+7;
    int n,m;
    int Siz[N<<2];
    double Max[N<<2];
    int qread()
    {
        int x=0;
        char ch=getchar();
        while(ch<'0' || ch>'9')ch=getchar();
        while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x;
    }
    int Calc(int l,int r,int rt,double v)
    {
        if(Max[rt]<=v)return 0;
        if(l==r)return Max[rt]>v;
        int mid=l+r>>1;
        if(Max[rt<<1]<=v)return Calc(mid+1,r,rt<<1|1,v);
        return Calc(l,mid,rt<<1,v)+Siz[rt]-Siz[rt<<1];
    }
    void Modify(int l,int r,int rt,int p,double v)
    {
        if(l==r)
        {
            Max[rt]=v;Siz[rt]=1;
            return;
        }
        int mid=l+r>>1;
        if(p<=mid)Modify(l,mid,rt<<1,p,v);
        else Modify(mid+1,r,rt<<1|1,p,v);
        Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
        Siz[rt]=Siz[rt<<1]+Calc(mid+1,r,rt<<1|1,Max[rt<<1]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        int x,y;
        while(m--)
        {
            x=qread();y=qread();
            Modify(1,n,1,x,1.0*y/x);
            printf("%d
    ",Siz[1]);
        }
        return 0;
    }
  • 相关阅读:
    iOS中图片与视频一次性多选
    UIImagePickerController Class
    1月16日
    10月20日
    1月14日
    1月13日
    1月12日
    1月11日
    课程评价与建议
    加分总结
  • 原文地址:https://www.cnblogs.com/LeTri/p/10108263.html
Copyright © 2011-2022 走看看