bzoj-2957 楼房重建
2015-07-08 20:12
465 查看
题意:
数轴上有n个楼,分别在1~n这些点上;
m次查询,每次改变一个楼的高度,问从(0,0)这个点可以看到多少楼;
题解:
对于一个楼来说要想看到这个楼,那么前面的楼的斜率一定比这个楼小;
那么考虑分块的话,就将块中楼的斜率都求出来;
然后维护出一个从块首元素开始的递增序列;
即包括块首元素的下标最小的序列;
扫一遍所有块,取该块之前的所有楼的最大斜率为ma;
在当前块中二分找比ma大的元素个数,并更新ma;
复杂度O(m*√n*log(√n)),时间基本和1s擦边;
但是BZ算的总时限所有可以无压力AC;
代码:
数轴上有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 , cnt[400]; double k , 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; }
相关文章推荐
- encodeURIComponent 的作用和encodeURI的区别
- HtmlParser学习系列 -- 学习总结
- Mac上配置Ant打包工具
- 20.顺时针打印矩阵
- struts2概述
- 凸优化:ADMM(Alternating Direction Method of Multipliers)交替方向乘子算法系列之十一:Numerical Examples
- 写一个 docker 打击一系列手册
- 实现基于Memcache存储的Session类
- nova 详解
- sizeof和strlen
- 南阳oj 题目29 求转置矩阵问题
- android studio集成友盟v2.3消息推送
- 凸优化:ADMM(Alternating Direction Method of Multipliers)交替方向乘子算法系列之十: Implementation
- leetcode 014 —— Longest Common Prefix
- javascript字符串对象
- [转]开发大型高负载类网站应用的几个要点
- cat命令
- Flatten Binary Tree to Linked List
- [转]榨干 PHP,不得不转的一篇PHP使用技巧!
- HttpClient 与 HtmlParser 简介