码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj-2957 楼房重建

时间:2015-07-08 20:58:53      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:bzoj   分块   

题意:

数轴上有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\n", ans);
	}
	return 0;
}


bzoj-2957 楼房重建

标签:bzoj   分块   

原文地址:http://blog.csdn.net/ww140142/article/details/46807597

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!