cf#345-C - Watchmen-map离散化
2016-03-07 22:18
253 查看
http://codeforces.com/contest/651/problem/C
给你n个点,要求有多少对点满足 |xi - xj| + |yi - yj|.=
.
也就是 这两个点 在平行于x或y轴的直线上
x,y的范围太大 1e9,但是n只有2e5
我们把点离散化后,看遍历所有与X轴平行的直线(当然就是只看出现过的x值),看上面有多少个点,如果有X个点,显然 X方向的这些点对答案的贡献就是 (x-1)*x/2
y轴同理
要注意的是,会有重合的点,重合的点 在X或Y方向 的贡献会被计算了两次
只需要把所有点排个序,找出重合点的个数,对于重合的A点X个,只需要减去一次贡献即可,也就是x*(x-1)/2
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
map<__int64 ,__int64 > ::iterator it;
map<__int64 ,__int64 > sbx,sby;
struct node
{
__int64 x,y;
};
bool cmp(node a,node b)
{
if (a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
node tm[200005];
int main()
{
int n;
cin>>n;
__int64 i;
for (i=1;i<=n;i++)
{
scanf("%I64d%I64d",&tm[i].x,&tm[i].y);
sbx[tm[i].x]++;
sby[tm[i].y]++;
}
sort(tm+1,tm+1+n,cmp);
__int64 ans=0;
for (it=sbx.begin();it!=sbx.end();it++)
{
__int64 tmp=it->second;
ans+=tmp*(tmp-1)/2;
}
for (it=sby.begin();it!=sby.end();it++)
{
__int64 tmp=it->second;
ans+=tmp*(tmp-1)/2;
}
__int64 ret=0;
for (i=1;i<=n;i++)
{
int j=i+1;
while (tm[i].x==tm[j].x&&tm[i].y==tm[j].y&&j<=n)
j++;
ret=j-i;
ans-=ret*(ret-1)/2;
i=j-1;
}
printf("%I64d\n",ans);
return 0;
}
给你n个点,要求有多少对点满足 |xi - xj| + |yi - yj|.=
.
也就是 这两个点 在平行于x或y轴的直线上
x,y的范围太大 1e9,但是n只有2e5
我们把点离散化后,看遍历所有与X轴平行的直线(当然就是只看出现过的x值),看上面有多少个点,如果有X个点,显然 X方向的这些点对答案的贡献就是 (x-1)*x/2
y轴同理
要注意的是,会有重合的点,重合的点 在X或Y方向 的贡献会被计算了两次
只需要把所有点排个序,找出重合点的个数,对于重合的A点X个,只需要减去一次贡献即可,也就是x*(x-1)/2
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
map<__int64 ,__int64 > ::iterator it;
map<__int64 ,__int64 > sbx,sby;
struct node
{
__int64 x,y;
};
bool cmp(node a,node b)
{
if (a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
node tm[200005];
int main()
{
int n;
cin>>n;
__int64 i;
for (i=1;i<=n;i++)
{
scanf("%I64d%I64d",&tm[i].x,&tm[i].y);
sbx[tm[i].x]++;
sby[tm[i].y]++;
}
sort(tm+1,tm+1+n,cmp);
__int64 ans=0;
for (it=sbx.begin();it!=sbx.end();it++)
{
__int64 tmp=it->second;
ans+=tmp*(tmp-1)/2;
}
for (it=sby.begin();it!=sby.end();it++)
{
__int64 tmp=it->second;
ans+=tmp*(tmp-1)/2;
}
__int64 ret=0;
for (i=1;i<=n;i++)
{
int j=i+1;
while (tm[i].x==tm[j].x&&tm[i].y==tm[j].y&&j<=n)
j++;
ret=j-i;
ans-=ret*(ret-1)/2;
i=j-1;
}
printf("%I64d\n",ans);
return 0;
}
相关文章推荐
- Struts1 struts2 springmvc3比较
- selector和shape的混搭使用
- 用js实现冒泡排序
- Swift开源项目精选
- Arm linux启动流程
- 编程学习第四天,更多的打印,以及初步的输入
- 1. 面试第一天 2015.03.07
- 框架源码学习笔记
- SPI与IIC
- 《机电传动控制》第三周仿真作业
- 利用sklearn计算文本相似性
- 算法学习
- convex hull trick CF344.E
- 服务器端开发技术
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- 栈与队列的真相(概述)
- CodeForces - 630B Moore's Law (快速幂)
- Codeforces 651C - Watchmen
- 软考中高项学员:2016年3月7日作业
- 2016.3.7