• bzoj-2957 楼房重建


    题意:

    数轴上有n个楼,分别在1~n这些点上;

    m次查询。每次改变一个楼的高度,问从(0,0)这个点能够看到多少楼;


    题解:
    对于一个楼来说要想看到这个楼。那么前面的楼的斜率一定比这个楼小;

    那么考虑分块的话。就将块中楼的斜率都求出来。

    然后维护出一个从块首元素開始的递增序列;

    即包含块首元素的下标最小的序列;

    扫一遍全部块。取该块之前的全部楼的最大斜率为ma;

    在当前块中二分找比ma大的元素个数。并更新ma。

    复杂度O(m*√n*log(√n)),时间基本和1s擦边;

    可是BZ算的总时限全部能够无压力AC。


    代码:


    #include<math.h>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 110001
    using namespace std;
    int bk, h[N], cnt[400];
    double k[N], q[400][400];
    int main()
    {
    	int n, m, i, j, index, x, y, ans;
    	double ma;
    	scanf("%d%d", &n, &m);
    	bk = sqrt(n);
    	for (i = 1; i <= m; i++)
    	{
    		scanf("%d%d", &x, &y);
    		h[x] = y;
    		k[x] = (double)y / x;
    		index = x / bk;
    		for (j = index*bk, ma = 0, cnt[index] = 0; j <= index*bk + bk - 1; j++)
    		if (k[j] > ma)
    			q[index][++cnt[index]] = k[j], ma = k[j];
    		ma = 0, ans = 0;
    		for (j = 0; j <= n / bk; j++)
    		{
    			ans += cnt[j] - (upper_bound(q[j] + 1, q[j] + 1 + cnt[j], ma) - q[j] - 1);
    			ma = max(ma, q[j][cnt[j]]);
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    


  • 相关阅读:
    Gitbook
    Docker命令
    sd
    文本三剑客
    2017.4.12下午
    2017.4.11下午
    2017.4.11上午
    2017.4.10下午
    2017.4.10上午
    2017.4.7下午
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5390140.html
Copyright © 2020-2023  润新知