zoukankan      html  css  js  c++  java
  • bzoj2957楼房重建——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2957

    线段树维护原点到楼顶的斜率,可以知道答案就是从原点开始斜率递增的个数;

    记录一个mx数组表示这一段上最大的斜率,二分,分类讨论,递归求解;

    而且如果要取rs的长度,不是直接取tr[rs],而是总长度减去tr[ls],因为不能从右边一段的起点开始……

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int const MAXN=100005;
    int n,m,tr[MAXN<<2];
    double xl[MAXN],mx[MAXN<<2];
    int find(int x,int l,int r,double w)
    {
        if(l==r)return xl[l]>w;
        int ls=(x<<1),rs=(x<<1|1);
        int mid=((l+r)>>1);
        if(mx[ls]>w)return tr[x]-tr[ls]+find(ls,l,mid,w);
        return find(rs,mid+1,r,w);
    }
    void pushup(int x,int l,int r)
    {
        int mid=((l+r)>>1);
        int ls=(x<<1),rs=(x<<1|1);
        if(mx[ls]>=mx[rs])tr[x]=tr[ls],mx[x]=mx[ls];
        else if(mx[ls]<xl[mid+1])tr[x]=tr[ls]+tr[rs],mx[x]=mx[rs];
        else
        {
            tr[x]=tr[ls]+find(rs,mid+1,r,mx[ls]);
            mx[x]=mx[rs];
        }
    }
    void add(int nw,int L,int R,int l,int r,double w)
    {
        if(l==r)
        {
            tr[nw]=1;mx[nw]=w;//!!!注意别把nw写成l 
            return;
        }
        int mid=((l+r)>>1);
        if(mid>=L)add(nw<<1,L,R,l,mid,w);
        if(mid<R)add(nw<<1|1,L,R,mid+1,r,w);
        pushup(nw,l,r);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1,x;i<=m;i++)
        {
            double y;
            scanf("%d%lf",&x,&y);
            xl[x]=y/x;
            add(1,x,x,1,n,xl[x]);
            printf("%d
    ",tr[1]);
        }
        return 0;
    }
  • 相关阅读:
    OpenCV程序在生产环境中运行
    C#调用C++导出(dllexport)方法
    IIS7.5 GZip配置
    wcf学习笔记--初识wcf
    Greenplum installation guide
    Cloudera 5.8.2 Installation guide
    WPF DataGrid 合并单元格
    wpf DataGrid CheckBox列全选
    WPF button 圆角制作
    WPF passwordbox 圆角制作
  • 原文地址:https://www.cnblogs.com/Zinn/p/8969398.html
Copyright © 2011-2022 走看看