• BZOJ2957 楼房重建


    题目链接:戳我

    线段树qwqwq动态维护最长上升子序列的长度

    对于一个区间,我们记录两个参数——(ans)表示这个区间里面的上升子序列的个数,(k)表示最大的斜率。

    关键是怎么合并?肯定是左区间的ans+右区间在左区间最大斜率的限制下的上升子序列个数。

    怎么计算右区间的那一部分?我们把右区间分成左子区间和右子区间。如果左子区间的最大斜率比当前限制斜率(即左区间最大斜率)大,右子区间相当于限制和原先一样,只要递归计算左子区间,再加上右子区间原本的贡献即可。(注意不是右子区间的sum,因为那个没有大于左边的限制,具体写法请见代码)。如果左子区间的最大斜率比限制斜率小,那左子区间就相当于全部都看不到了,所以递归计算右子区间即可qwqwq

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    using namespace std;
    #define MAXN 100010
    int n,m;
    struct Node{int l,r,sum;double maxx;}t[MAXN<<2];
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    inline void build(int x,int l,int r)
    {
        t[x].l=l,t[x].r=r;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(ls(x),l,mid);
        build(rs(x),mid+1,r);
    }
    inline int calc(int x,double k)
    {
        int l=t[x].l,r=t[x].r;
        if(l==r) 
        {
            if(t[x].maxx>k) return 1;
            else return 0;
        }
        if(t[ls(x)].maxx<=k) return calc(rs(x),k);
        else return calc(ls(x),k)+t[x].sum-t[ls(x)].sum;
    }
    inline void update(int x,int pos,double k)
    {
        int l=t[x].l,r=t[x].r;
        if(l==r) 
        {
            t[x].maxx=k;
            t[x].sum=1;
            return;
        }
        int mid=(l+r)>>1;
        if(pos<=mid) update(ls(x),pos,k);
        else update(rs(x),pos,k);
        t[x].maxx=max(t[ls(x)].maxx,t[rs(x)].maxx);
        t[x].sum=t[ls(x)].sum+calc(rs(x),t[ls(x)].maxx);
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        freopen("ce.out","w",stdout);
        #endif 
        scanf("%d%d",&n,&m);
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            int x,h;
            scanf("%d%d",&x,&h);
            double cur=1.0*h/x;
            update(1,x,cur);
            printf("%d
    ",t[1].sum);
        }
        return 0;
    }
    
  • 相关阅读:
    php 解析json
    TP学习笔记一(tp的目录结构 , tp的输出方式)
    linux android真机测试
    SharedPreferences保存数据
    Volley用法
    android获得图片
    android 一条线
    android 获取时间
    Android_Spinner_Listener
    Android_Spinner_SimpleAdapter
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10521386.html
Copyright © 2020-2023  润新知