zoukankan      html  css  js  c++  java
  • [BZOJ2957] 楼房重建 (线段树,递归)

    题目链接


    Solution

    经典的一道线段树题,难点在于如何合并节点.
    由于题目要求直线要求不相交,则斜率均大于前面的点即为答案.
    所以以斜率为权值.
    考虑线段树每一个节点维护两个值:

    • (Max) 代表当前节点中的最大值.
    • (Sum) 代表对于任意一个节点 (i) , 其中满足(w_j>Max(w_{l[i]},w_{l[i]+1}...,w_{r[i]}))的个数,其中 (l[i]),(r[i]) 指节点 (i) 所在的区间左右端点.(w)为斜率.

    每一次插入一个节点,它仅会对沿途的最大值和答案产生影响.
    然后每次将已经统计好左儿子的 (Max) 加入与右儿子中的答案进行比较,递归完成整棵线段树.
    然后详情可以看代码.

    Code

    #include<bits/stdc++.h>
    #define N 100008
    using namespace std;
    
    struct node{double max;int sum;}sgm[N*4];
    int n,m,x,k;
    
    int Calc(int node,double maxn,int l,int r)
    {
        int mid=(l+r)>>1;
        if (l==r) return sgm[node].max>maxn;
        if (sgm[node].max<=maxn) return 0;
        //如果当前节点最大值均已不能统计,直接返回.
        if (sgm[node<<1].max<=maxn) return Calc(node<<1|1,maxn,mid+1,r);
        else return sgm[node].sum-sgm[node<<1].sum+Calc(node<<1,maxn,l,mid);
    }
    
    void Update(int node,int l,int r,int x,double k)
    {
        if (l==r)
        {
            sgm[node].max=k;
            sgm[node].sum=1;
            return;
        }
        int mid=(l+r)>>1;
        if (x<=mid) Update(node<<1,l,mid,x,k);
        else Update(node<<1|1,mid+1,r,x,k);
        sgm[node].max=max(sgm[node<<1].max,sgm[node<<1|1].max);
        sgm[node].sum=sgm[node<<1].sum+Calc(node<<1|1,sgm[node<<1].max,mid+1,r);
        //左边已经处理完,逐层递归返回
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1; i<=m; ++i)
        {
            scanf("%d%d",&x,&k);
            Update(1,1,n,x,k*1.0/x);
            printf("%d
    ",sgm[1].sum);
        }
    }
    
    
    
  • 相关阅读:
    对象池使用时要注意几点
    Flash3D学习计划(一)——3D渲染的一般管线流程
    714. Best Time to Buy and Sell Stock with Transaction Fee
    712. Minimum ASCII Delete Sum for Two Strings
    647. Palindromic Substrings(马拉车算法)
    413. Arithmetic Slices
    877. Stone Game
    338. Counting Bits
    303. Range Sum Query
    198. House Robber
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/9738942.html
Copyright © 2011-2022 走看看