Watchmen are in a danger and Doctor Manhattan together with his friend Daniel Dreiberg should warn them as soon as possible. There are n watchmen on a plane, the i-th watchman is located at point (xi, yi).
They need to arrange a plan, but there are some difficulties on their way. As you know, Doctor Manhattan considers the distance between watchmen i and j to be |xi - xj| + |yi - yj|. Daniel, as an ordinary person, calculates the distance using the formula .
The success of the operation relies on the number of pairs (i, j) (1 ≤ i < j ≤ n), such that the distance between watchman i and watchmen j calculated by Doctor Manhattan is equal to the distance between them calculated by Daniel. You were asked to compute the number of such pairs.
题目大意:发现有一些点的欧氏距离和曼哈顿距离是相等的,他认为这个现象特别有趣。为了发现一些规律和性质,他给出了 n 个点,想知道这些点中有多少对点的欧氏距离与曼哈顿距离相等
The first line of the input contains the single integer n (1 ≤ n ≤ 200 000) — the number of watchmen.
Each of the following n lines contains two integers xi and yi (|xi|, |yi| ≤ 109).
Some positions may coincide.
Print the number of pairs of watchmen such that the distance between them calculated by Doctor Manhattan is equal to the distance calculated by Daniel.
3
1 1
7 5
1 5
2
6
0 0
0 1
0 2
-1 1
0 1
1 1
11
In the first sample, the distance between watchman 1 and watchman 2 is equal to |1 - 7| + |1 - 5| = 10 for Doctor Manhattan and for Daniel. For pairs (1, 1), (1, 5) and (7, 5), (1, 5) Doctor Manhattan and Daniel will calculate the same distances.
比较容易发现,两个点 A 和 B 能够贡献答案当且仅当 A 和 B 有至少一维坐标相等。于是
我们离散化以后对于每个相同的 x 和 y 坐标统计一下答案就好了。
注意可能有坐标相同的点,这些点对会在 x 坐标和 y 坐标上都贡献一次答案,所以要去重。
时间复杂度 O(n log n) 。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
struct Pair
{
int x,y;
bool operator <(const Pair &z)
const
{
return (x<z.x||(x==z.x&&y<z.y));
}
};
map<Pair,int>Map;
int X[],Y[],a[],x[],y[],n,sz;
long long ans;
int main()
{int i;
cin>>n;
for (i=;i<=n;i++)
{
scanf("%d%d",&x[i],&y[i]);
a[i]=x[i];a[n+i]=y[i];
}
sz=unique(a+,a+*n+)-(a+);
sort(a+,a+sz+);
for (i=;i<=n;i++)
{
x[i]=lower_bound(a+,a+sz+,x[i])-a;
y[i]=lower_bound(a+,a+sz+,y[i])-a;
}
for (i=;i<=n;i++)
{
if (Map.count((Pair){x[i],y[i]})) ans-=Map[(Pair){x[i],y[i]}];
ans+=X[x[i]]+Y[y[i]];
if (Map.count((Pair){x[i],y[i]}))
Map[(Pair){x[i],y[i]}]++;
else Map[(Pair){x[i],y[i]}]=;
X[x[i]]++;Y[y[i]]++;
}
cout<<ans;
}