公式
a
n
s
+
=
c
n
t
[
x
]
+
c
n
t
[
y
]
−
2
∗
c
n
t
[
x
,
y
]
+
c
n
t
[
y
+
x
]
+
c
n
t
[
y
−
x
]
ans+=cnt[x]+cnt[y]-2 * cnt[x,y]+cnt[y+x]+cnt[y-x]
ans+=cnt[x]+cnt[y]−2∗cnt[x,y]+cnt[y+x]+cnt[y−x]
c
n
t
[
x
]
+
c
n
y
[
y
]
−
2
∗
c
n
t
[
x
,
y
]
cnt[x]+cny[y]-2 * cnt[x,y]
cnt[x]+cny[y]−2∗cnt[x,y]是统计坐标轴方向的,-2倍是需要把本身这个点给减去容斥是减一倍,这里还需要把自己给挖掉
c
n
t
[
y
+
x
]
+
c
n
t
[
y
−
x
]
cnt[y+x]+cnt[y-x]
cnt[y+x]+cnt[y−x]是统计对角线方向的。这也是一种常用的表示对角线的技巧
#include<bits/stdc++.h>#defineintlonglong#definerep(i, a, b)for(int i =(a); i <=(b);++i)#definefep(i, a, b)for(int i =(a); i >=(b);--i)#define_for(i, a, b)for(int i=(a); i<(b);++i)#definepiipair<int,int>#definepddpair<double,double>#definelllonglong#definedbdouble#defineendl'\n'#definexfirst#defineysecond#definepbpush_back#definevivector<int>/*
* 思路:用map记录x,y,以及y-x、y+x
* 从前往后统计一遍答案即可
*/usingnamespace std;constint maxn =2e5+10;
pii a[maxn];voidsolve(){int n;
cin>>n;
map<int,int>cntx,cnty,cntd,cnts;
map<pii,int>cnt;int ans=0;rep(i,1,n){
cin>>a[i].x>>a[i].y;}sort(a+1,a+1+n);rep(i,1,n){int x=a[i].x,y=a[i].y;
ans+=cntx[x];
ans+=cnty[y];//容斥
ans-=2*cnt[{x,y}];
ans+=cntd[y-x];
ans+=cnts[y+x];
cntx[x]+=1;
cnty[y]+=1;
cntd[y-x]+=1;
cnts[y+x]+=1;
cnt[{x,y}]+=1;}
cout<<ans*2<<endl;}signedmain(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);// freopen("C:\\Users\\24283\\CLionProjects\\untitled2\\1.in", "r", stdin);int _;
cin >> _;while(_--)solve();return0;}