codeforces 651C Watchmen
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) 。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<map> 6 using namespace std; 7 struct Pair 8 { 9 int x,y; 10 bool operator <(const Pair &z) 11 const 12 { 13 return (x<z.x||(x==z.x&&y<z.y)); 14 } 15 }; 16 map<Pair,int>Map; 17 int X[400005],Y[400005],a[400005],x[200005],y[200005],n,sz; 18 long long ans; 19 int main() 20 {int i; 21 cin>>n; 22 for (i=1;i<=n;i++) 23 { 24 scanf("%d%d",&x[i],&y[i]); 25 a[i]=x[i];a[n+i]=y[i]; 26 } 27 sz=unique(a+1,a+2*n+1)-(a+1); 28 sort(a+1,a+sz+1); 29 for (i=1;i<=n;i++) 30 { 31 x[i]=lower_bound(a+1,a+sz+1,x[i])-a; 32 y[i]=lower_bound(a+1,a+sz+1,y[i])-a; 33 } 34 for (i=1;i<=n;i++) 35 { 36 if (Map.count((Pair){x[i],y[i]})) ans-=Map[(Pair){x[i],y[i]}]; 37 ans+=X[x[i]]+Y[y[i]]; 38 if (Map.count((Pair){x[i],y[i]})) 39 Map[(Pair){x[i],y[i]}]++; 40 else Map[(Pair){x[i],y[i]}]=1; 41 X[x[i]]++;Y[y[i]]++; 42 } 43 cout<<ans; 44 }