zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    SCAU 9504 面试
    SCAU 9503 懒人选座位
    SCAU 8628 相亲
    SCAU 10691 ACM 光环
    SCAU 8626 原子量计数
    SCAU 10674 等差对
    HDU ACM 1048 The Hardest Problem Ever (水题)
    SCAU 9502 ARDF
    SCAU 10686 DeathGod不知道的事情
    SCAU 8629 热身游戏(高精度)
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10521386.html
Copyright © 2011-2022 走看看