【codeforces 650A】【思维】【容斥】【数学】【求n个点中两种距离相等的点对数】

时间:2019-01-19
本文章向大家介绍【codeforces 650A】【思维】【容斥】【数学】【求n个点中两种距离相等的点对数】,主要包括【codeforces 650A】【思维】【容斥】【数学】【求n个点中两种距离相等的点对数】使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

【链接】https://codeforces.com/problemset/problem/650/A

【一句话题解】求n个点中两种距离相等的点对数。SX U SY =SX+SY +SX ∩ SY,x,y分别排序,map记录点对,容斥算重

【代码】

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int maxn = 1e6 + 6;
int x[maxn], y[maxn];

int cmp(int a, int b) {
	return a < b;
}
map<int, map<int,int> >mp,vis;

int main() {
	int n;
	while (~scanf("%d", &n)) {
		for (int i = 0; i < n; i++) {
			scanf("%d%d", &x[i], &y[i]);
			mp[x[i]][y[i]]++;
		}
		ll ans = 0;

		for (int i = 0; i < n; i++) {
			if (mp[x[i]][y[i]]>1&&!vis[x[i]][y[i]])ans-= (mp[x[i]][y[i]]-1LL)*(mp[x[i]][y[i]])/2;
			vis[x[i]][y[i]] = 1;
		}
		sort(x, x + n, cmp);
		sort(y, y + n, cmp);
		
		for (ll i = 0; i < n; i++) {
			if (i!=0&&x[i] == x[i - 1])continue;
			ll j = lower_bound(x, x + n, x[i] + 1)-x;
			ans += (j - i - 1LL)*(j - i )/2;
		}
		for (ll i = 0; i < n; i++) {
			if (i!=0&&y[i] == y[i - 1])continue;
			ll j = lower_bound(y, y + n, y[i] + 1) - y;
			ans += (j - i - 1LL)*(j - i )/2;
		}
		cout << ans << endl;
	}
}

/*
3
1 1
7 5
1 5

*/

/*

6
0 0
0 1
0 2
-1 1
0 1
1 1

*/

/*

3
1 2
1 2
1 2

*/