题意:找出有多少对点是|xi - xj| + |yi - yj|=
解题思路:只要一个坐标x或y中一个与另一个坐标x或y相等就行,那么搞两个数组,一个按照x排序,
一个按照y排序,找出相同的,按排列组合公式计算。但要注意有可能如果有相同的点,
那么就会多算了一次这些相同的点,故最后减去相同的点的组合数。
/* ***********************************************
┆ ┏┓ ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃ ┃ ┆
┆┃ ━ ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃ ┃ ┆
┆┃ ┻ ┃ ┆
┆┗━┓ 马 ┏━┛ ┆
┆ ┃ 勒 ┃ ┆
┆ ┃ 戈 ┗━━━┓ ┆
┆ ┃ 壁 ┣┓┆
┆ ┃ 的草泥马 ┏┛┆
┆ ┗┓┓┏━┳┓┏┛ ┆
┆ ┃┫┫ ┃┫┫ ┆
┆ ┗┻┛ ┗┻┛ ┆
************************************************ */
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define ull unsigned long long
#define maxn 200005
#define f first
#define se second
typedef pair<int,int> p;
vector<p> sx;
vector<p> sy;
int main()
{
int n;
int x,y;
cin>>n;
for(int i=0;i<n;i++)
{
scanf("%d%d",&x,&y);
sx.push_back(p(x,y));
sy.push_back(p(y,x));
}
sort(sx.begin(),sx.end());
sort(sy.begin(),sy.end());
int temp=sx[0].f;
ll cnt=1,sumx=0;
for(int i=1;i<n;i++)
{
if(sx[i].f==temp)
{
cnt++;
}
else
{
sumx+=(cnt*(cnt-1))/2;
cnt=1;
temp=sx[i].f;
}
}
sumx+=(cnt*(cnt-1))/2;
//cout<<sumx<<endl;
cnt=1;
ll sumy=0;
temp=sy[0].f;
for(int i=1;i<n;i++)
{
if(sy[i].f==temp)
{
cnt++;
}
else
{
sumy+=(cnt*(cnt-1))/2;
cnt=1;
temp=sy[i].f;
}
}
sumy+=(cnt*(cnt-1))/2;
//cout<<sumy<<endl;
int temp2,temp1;
temp2=sx[0].se;
temp1=sx[0].f;
cnt=1;
ll sub=0;
for(int i=1;i<n;i++)
{
if(sx[i].f==temp1 && sx[i].se==temp2)
{
cnt++;
}
else
{
sub+=(cnt*(cnt-1))/2;
cnt=1;
temp2=sx[i].se;
temp1=sx[i].f;
}
}
sub+=(cnt*(cnt-1))/2;
cout<<sumx+sumy-sub<<endl;
return 0;
}