HDU 2366 Space(二分计数)
One line with two integers n (1 <= n <= 100 000) and d (1 <= d <= 50): the number of teams and the minimum distance between two teams.
n lines with two integers xi (0 <= xi <= 1 000 000 000) and yi (0 <= yi <= 1 000 000 000): the coordinates of the i-th team. No two teams will have the same coordinates.
One line with the number of pairs of teams that sit too close to each other.
题目大意:给平面上n个点,问有多少对点间的距离小于d。
思路:一眼可以看到,虽然x轴和y轴的范围很大,但是d却很小,这应该是一个突破口。
那么这个d怎么利用呢。思考一下,对于任意一个点P,和它的距离小于d的点,至少应该在一个以P为中心的2d*2d的正方形中。
因为要题目要求的是对数,那么我们可以只考虑P点的右半部分的点(因为左边部分的点与P的组合在计算左边的点的时候已经算了)。
那么,我们就是要考虑,对于点P(x0, y0),只考虑x = x0、x0+1、……、x0+d-1的点。
穷举这些x = x0 + i,那么y轴的范围就应该在[y0 - t, y0 + t]之间,其中 t 是满足i^2 + t^2 < d^2的最大整数(注意题目都是整点)。
如果对于每一个x = x0 + i的点我们都可以收集起来,按y轴排好,那么二分查找,可以得到 结果 = 小于等于y0 + t的数目 - 小于y0 - t的数目。
因为x的范围很大,不可能说每个点开个数组,我们可以用C++的map存起来,每个有可能的x开一个vector,然后排序即可(注意找map中是否存在x的时候最好用map.find(x),直接用map[x]会创建一个x留在map中,可能导致效率的减缓)。
如果不用map也不是不可以,只要把点都从小到大(x轴为第一关键字,y轴第二关键字)排好序,每次需要哪个x的时候二分查找也是可以的。
我们好像还没算x轴相同的呢。对于x轴相同的,弄俩指针,从前往后扫就可以统计出来了,这个还是不难的。
细节可以看代码,时间复杂度为O(n*d*log(n))。
代码(14109MS):
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
typedef long long LL; const int MAXN = ; int T, n, d, x, y;
map<int, vector<int> > mymap; LL solve() {
LL ans = ;
for(map<int, vector<int> >::iterator it = mymap.begin(); it != mymap.end(); ++it) {
sort(it->second.begin(), it->second.end());
for(int i = , j = , n = it->second.size(); i < n; ++i) {
while(j < n && it->second[i] + d > it->second[j]) ++j;
ans += j - i - ;
}
}
int d2 = d * d;
for(map<int, vector<int> >::iterator it = mymap.begin(); it != mymap.end(); ++it) {
for(vector<int>::iterator p = it->second.begin(); p != it->second.end(); ++p) {
for(int i = , t = d; i < d; ++i) {
while(i * i + t * t >= d2) --t;
map<int, vector<int> >::iterator nx = mymap.find(it->first + i);
if(nx != mymap.end()) {
ans += (upper_bound(nx->second.begin(), nx->second.end(), *p + t) - nx->second.begin()) -
(lower_bound(nx->second.begin(), nx->second.end(), *p - t) - nx->second.begin());
}
}
}
}
return ans;
} int main() {
scanf("%d", &T);
while(T--) {
mymap.clear();
scanf("%d%d", &n, &d);
for(int i = ; i < n; ++i) {
scanf("%d%d", &x, &y);
mymap[x].push_back(y);
}
printf("%I64d\n", solve());
}
}
HDU 2366 Space(二分计数)的更多相关文章
- hdu 2962 Trucking (二分+最短路Spfa)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 Trucking Time Limit: 20000/10000 MS (Java/Others ...
- UVA 10816 + HDU 1839 Dijstra + 二分 (待研究)
UVA 题意:两个绿洲之间是沙漠,沙漠的温度不同,告诉起点,终点,求使得从起点到终点的最高温度最小的路径,如果有多条,输出长度最短的路径: 思路:用最小费用(最短路径)最大流(最小温度)也能搞吧,但因 ...
- hdu 2413(最大匹配+二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2413 思路:由于要求最少的时间,可以考虑二分,然后就是满足在limit时间下,如果地球战舰数目比外星战 ...
- HDU 5884 Sort (二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5884 nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的 ...
- hdu 1281棋盘游戏(二分匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1281 Problem Description 小希和Gardon在玩一个游戏:对一个N*M的棋盘, ...
- HDU 1025 DP + 二分
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1025 求最长递增子序列,O(n^2)的复杂度超时,需要优化为O(n*logn) f[i]存储长度为i的最小 ...
- hdu 2289 要二分的杯子
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2289 大意是 一个Cup,圆台形,给你它的顶部圆的半径,底部圆的半径,杯子的高度,和此时里面装的水的体 ...
- HDU 1025 LIS二分优化
题目链接: acm.hdu.edu.cn/showproblem.php?pid=1025 Constructing Roads In JGShining's Kingdom Time Limit: ...
- HDU 5200 Trees 二分
题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5200 bc(中文):http://bestcoder.hdu.edu.cn/contests ...
随机推荐
- Java高级之线程同步
本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 关于实现多线程的意义,"从业四年看并发"一文已经讲述,而本篇主要讲一下常用的设计 ...
- 分布式集群中,设定时间同步服务器,以及ntpd与ntpdate的区别
什么时候配置时间同步? 当分布式集群配置好了以后,马上配置的是SSH无密钥配置,然后就是配置时间同步. 时间同步在集群中特别重要. 一:时间同步 1.时间同步 集群中必须有一个统一的时间 如果是内网, ...
- PHP 日期比较
$temptime = mktime(8,2,12,4,4,2014);$dt1 = date("Y-m-d",time());$dt2 = date("Y-m-d&qu ...
- TCP/IP和HTTP的举例理解
闲暇中逛博客园,看到TCP/IP和HTTP关键词,就突然想深刻理解他们(以前真的是只知皮毛),于是看了关于TCP/IP和HTTP的博文,就有了此文. 首先要引出开放系统互连参考模型(OSI:Open ...
- iOS 使用封装的NSLog来打印调试信息
//DLog代替NSLog //debugMethod() 代替 NSLog(@"%s", __func__) //DLog在release下不会输出 #ifdef DEBUG # ...
- How to Iterate Map
常用iterate 方法 Map<Integer, String> m = new HashMap<Integer, String>(); for(Map.Entry<I ...
- android开源框架
1.volley 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载: (2) 网络请求的排序(scheduli ...
- 最常用App开发工具更新总结
程序员都知道,App常用开发工具有Sublime Text 3.Webstorm.Eclipse和APICloud Studio等,那么这些开发工具在2016年又有什么重大更新呢? 1.APIClou ...
- 数据库笔记--常见sql操作
1.数据库联表查询: 在实际项目中有时需要将两个表结合到一起进行查询,此处介绍其语法: 左连接查询:select * from tableA left join tableB on tableA.fi ...
- MongoDB概念解析
数据库 MongoDB默认把_id设置为主键(_开头的键是保留的) 数据库名必须为小写 RDBMS与MongoDB对应的术语比较 需注意 文档中的键/值对是有序的. 文档中的值不仅可以是在双引号里面的 ...