1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include<cstdio> #include<bitset> #include<vector> #include<deque> #include<cstring> #include<algorithm> using namespace std; const int N=2010,FSIZE=1<<24,MX=200010; using uni=unsigned; using ll=long long; using db=double; int x[N],y[N],w[MX],pr[MX/10]; bool no[MX]; struct line{int d,x;}; struct line2{int d,x,y;}; bitset<N> pre[N],mid[N],suf[N],none; deque<line> a[N]; deque<line>::iterator l[N],r[N]; vector<line2> all; line2 tmp[N*N]; char BuF[FSIZE],*InF=BuF; template<typename T>void read(T &x){ bool f=1; for(;48>*InF||*InF>57;f^=*InF++=='-'); for(x=0;47<*InF&&*InF<58;x=x*10+(*InF++^48)); x=f?x:-x; } int dis(int i,int j){ return(abs(x[i]-x[j])+abs(y[i]-y[j])); } void get(int x,int d){ for(;r[x]!=a[x].end()&&r[x]->d<=d;++r[x]){ mid[x][r[x]->x]=1; suf[x][r[x]->x]=0; } for(;l[x]!=a[x].end()&&l[x]->d<d;++l[x]){ pre[x][l[x]->x]=1; mid[x][l[x]->x]=0; } } template<class T>void Sort(T beg,T end){ memset(w,0,sizeof(w)); for(auto i=beg;i<end;++w[i++->d]); for(int *i=w,*r=w+MX;i<r;++i) *(i+1)+=*i; for(auto i=beg;i<end;++i) tmp[--w[i->d]]=*i; memcpy(&*beg,tmp,(end-beg)*sizeof(line2)); } void work(){ int n,m; ll ans1=0,ans3=0; read(n);read(m); all.clear(); for(int i=1;i<=n;++i){ read(x[i]);read(y[i]); a[i].clear(); } for(int i=1;i<n;++i) for(int j=i+1;j<=n;++j) all.push_back({dis(i,j),i,j}); Sort(all.begin(),all.end()); for(auto i:all){ a[i.x].push_back({i.d,i.y}); a[i.y].push_back({i.d,i.x}); } for(int i=1;i<=n;++i){ pre[i].reset(); mid[i].reset(); suf[i].reset(); l[i]=r[i]=a[i].begin(); for(auto j:a[i]) suf[i][j.x]=1; } none.set(); for(auto i:all) if(!no[i.d]){ get(i.x,i.d); get(i.y,i.d); none[i.x]=none[i.y]=0; ans1+=(((pre[i.x]&suf[i.y])|(pre[i.y]&suf[i.x]))&none).count(); ans3+=(mid[i.x]&mid[i.y]&none).count(); none[i.x]=none[i.y]=1; } for(int i=1;i<=n;++i){ auto j=a[i].begin(),k=j; for(;j!=a[i].end();j=k){ for(k=j;j->d==k->d&&k<a[i].end();++k); if(!no[j->d]) ans1+=(k-j)*(k-j-1)>>1; if(k==a[i].end()) break; } } printf("%lld\n",ans1-(ans3/3)*2); } int main(){ fread(BuF,1,FSIZE,stdin); int t; no[1]=1; for(int i=2,cnt=0;i<MX;++i){ if(!no[i]) pr[cnt++]=i; for(int j=0;j<cnt&&i*pr[j]<MX;++j){ no[i*pr[j]]=1; if(!(i%pr[j])) break; } } for(read(t);t--;work()); fclose(stdin); fclose(stdout); return(0); }
|