Problem: Example

Input

2 2 3
0 0
2 0
0 0
0 2
0 0
1 1
1 1


Output

3

Solution (in CPP):

Solution:
bool debug=false;
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <utility>
#include <map>
#include <math.h>
using namespace std;
#define PB push_back
#define F first
#define S second
const int INF=1e9+10;
const int N=1e5+10;
const double pi=acos(-1);
pair<int,int> getmid(pair<int,int> a,pair<int,int> b){
	if(((a.F+b.F)&1)||((a.S+b.S)&1))return {INF,INF};
	return {(a.F+b.F)>>1,(a.S+b.S)>>1};
}
pair<int,int> getnxt(pair<int,int> a,pair<int,int> c){
	return {(c.F-a.F)*2+a.F,(c.S-a.S)*2+a.S};
}
__int128 myabs(__int128 x){return x>0?x:-x;}
pair<int,int> intersect(__int128 Aa,__int128 Ba,__int128 Ca,__int128 Ab,__int128 Bb,__int128 Cb){
	__int128 x=Ba*Cb-Bb*Ca,y=Ca*Ab-Cb*Aa,det=Ba*Ab-Aa*Bb;
	if(x%det!=0)return {INF,INF};
	if(y%det!=0)return {INF,INF};
	x/=det;
	y/=det;
	if(myabs(x)>N)return {INF,INF};
	if(myabs(y)>N)return {INF,INF};
	return {x,y};
}
pair<double,double> mul(pair<double,double> a,pair<double,double> b){
	return {a.F*b.F-a.S*b.S,a.F*b.S+a.S*b.F};
}
void fft(vector<pair<double,double>>& v,int size,bool on){
    pair<double,double> wn,u,t,w,inv;
	for(int i=1,j=size>>1,k;i<(size-1);i++){
        if(i<j)swap(v[i],v[j]);
        k=size>>1;
        while(j&k){
            j^=k;
            k>>=1;
        }
        j|=k;
    }
    for(int i=2;i<=size;i<<=1){
        wn={cos(2*pi/i),sin(2*pi/i)};
		if(on)wn.S=-wn.S;
        for(int j=0;j<size;j+=i){
            w={1,0};
            for(int k=j;k<j+(i>>1);k++){
                u=v[k];
                t=mul(w,v[k+(i>>1)]);
                v[k]={u.F+t.F,u.S+t.S};
                v[k+(i>>1)]={u.F-t.F,u.S-t.S};
                w=mul(wn,w);
            }
        }
    }
    if(on){
        inv={1.0/size,0};
        for(int i=0;i<size;i++)v[i]=mul(v[i],inv);
    }
    return ;
}
long long int allsame(vector<pair<int,int>>&va,vector<pair<int,int>>&vb,vector<pair<int,int>>&vc){
	vector<pair<double,double>> a,b;
	vector<long long int> c;
	long long int ans=0;
	int n=N<<2,sz=1;
	while(sz<n)sz<<=1;
	a.resize(sz,{0,0});
	b.resize(sz,{0,0});
	c.resize(sz>>1,0);
	if(va[0].F==va.back().F){
		for(pair<int,int> i:va)a[i.S+N].F+=1;
		for(pair<int,int> i:vb)b[i.S+N].F+=1;
		for(pair<int,int> i:vc)c[i.S+N]++;
	}
	else{
		for(pair<int,int> i:va)a[i.F+N].F+=1;
		for(pair<int,int> i:vb)b[i.F+N].F+=1;
		for(pair<int,int> i:vc)c[i.F+N]++;
	}
	if(debug){
		printf("a::\n");for(int i=0;i<sz;i++)if(a[i].F>0)printf("%d::(%.2lf,%.2lf)\n",i,a[i].F,a[i].S);
		printf("b::\n");for(int i=0;i<sz;i++)if(b[i].F>0)printf("%d::(%.2lf,%.2lf)\n",i,b[i].F,b[i].S);
	}
	fft(a,sz,0);
	fft(b,sz,0);
	for(int i=0;i<a.size();i++)a[i]=mul(a[i],b[i]);
	fft(a,sz,1);
	if(debug){
		printf("after::\n");for(int i=0;i<sz;i++)if(a[i].F>0)printf("%d::(%.2lf,%.2lf)\n",i,a[i].F,a[i].S);
		printf("c::\n");for(int i=0;i<(sz>>1);i++)if(c[i]>0)printf("%d::%d\n",i,c[i]);
	}
	for(int i=0;i<(sz>>1);i++)ans+=c[i]*((long long int)(a[i<<1].F+0.5));
	return ans;
}
long long int ABsame(vector<pair<int,int>>&va,vector<pair<int,int>>&vb,vector<pair<int,int>>&vc){
	vector<pair<double,double>> a,b;
	int n=N<<2,sz=1;
	pair<int,int> temp;
	long long int Aa,Ba,Ca,Cb,Ac,Bc,Cc;
	while(sz<n)sz<<=1;
	a.resize(sz,{0,0});
	b.resize(sz,{0,0});
	if(va[0].F==va.back().F){
		for(pair<int,int> i:va)a[i.S+N].F+=1;
		for(pair<int,int> i:vb)b[i.S+N].F+=1;
	}
	else{
		for(pair<int,int> i:va)a[i.F+N].F+=1;
		for(pair<int,int> i:vb)b[i.F+N].F+=1;
	}
	fft(a,sz,0);
	fft(b,sz,0);
	for(int i=0;i<a.size();i++)a[i]=mul(a[i],b[i]);
	fft(a,sz,1);
	Aa=va[0].S-va.back().S,Ba=va.back().F-va[0].F;
	Ca=Aa*va[0].F+Ba*va[0].S;
	Cb=Aa*vb[0].F+Ba*vb[0].S;
	Ac=vc[0].S-vc.back().S,Bc=vc.back().F-vc[0].F;
	Cc=Ac*vc[0].F+Bc*vc[0].S;
	temp=intersect(Aa*2,Ba*2,Ca+Cb,Ac,Bc,Cc);
	if(va[0].F==va.back().F)return ((long long int)(a[(temp.S+N)<<1].F+0.5))*(upper_bound(vc.begin(),vc.end(),temp)-lower_bound(vc.begin(),vc.end(),temp));
	else return ((long long int)(a[(temp.S+N)<<1].F+0.5))*(upper_bound(vc.begin(),vc.end(),temp)-lower_bound(vc.begin(),vc.end(),temp));
}
long long int ACsame(vector<pair<int,int>>&va,vector<pair<int,int>>&vb,vector<pair<int,int>>&vc){
	vector<pair<double,double>>a,b;
	vector<long long int> c;
	int n=N<<2,sz=1;
	long long int ans=0,Aa,Ba,Ca,Ab,Bb,Cb,Cc;
	pair<int,int> temp;
	while(sz<n)sz<<=1;
	a.resize(sz,{0,0});
	b.resize(sz,{0,0});
	c.resize(sz>>1,0);
	Aa=va[0].S-va.back().S,Ba=va.back().F-va[0].F;
	Ca=Aa*va[0].F+Ba*va[0].S;
	Cc=Aa*vc[0].F+Ba*vc[0].S;
	Ab=vb[0].S-vb.back().S,Bb=vb.back().F-vb[0].F;
	Cb=Ab*vb[0].F+Bb*vb[0].S;
	temp=intersect(Aa,Ba,Cc*2-Ca,Ab,Bb,Cb);
	if(temp.F>=N||temp.S>=N)return 0;
	if(va[0].F==va.back().F){
		for(pair<int,int> i:va)a[i.S+N].F+=1;
		for(pair<int,int> i:vc)c[i.S+N]++;
		b[temp.S+N].F=upper_bound(vb.begin(),vb.end(),temp)-lower_bound(vb.begin(),vb.end(),temp);
	}
	else{
		for(pair<int,int> i:va)a[i.F+N].F+=1;
		for(pair<int,int> i:vc)c[i.F+N]++;
		b[temp.F+N].F=upper_bound(vb.begin(),vb.end(),temp)-lower_bound(vb.begin(),vb.end(),temp);
	}
	fft(a,sz,0);
	fft(b,sz,0);
	for(int i=0;i<sz;i++)a[i]=mul(a[i],b[i]);
	fft(a,sz,1);
	for(int i=0;i<(sz>>1);i++)ans+=c[i]*((long long int)(a[i<<1].F+0.5));
	return ans;
}
int main(){
	int a,b,c;
	__int128 Aa,Ab,Ac,Ba,Bb,Bc,Ca,Cb,Cc;
	long long int ans=0;
	map<pair<int,int>,long long int> ma,mb,mc;
	map<pair<int,int>,long long int>::iterator u,t;
	pair<int,int> temp;
	vector<pair<int,int>> va,vb,vc;
	scanf("%d%d%d",&a,&b,&c);
	for(int i=1;i<=a;i++){
		scanf("%d%d",&temp.F,&temp.S);
		va.PB(temp);
		ma[temp]++;
	}
	for(int i=1;i<=b;i++){
		scanf("%d%d",&temp.F,&temp.S);
		vb.PB(temp);
		mb[temp]++;
	}
	for(int i=1;i<=c;i++){
		scanf("%d%d",&temp.F,&temp.S);
		vc.PB(temp);
		mc[temp]++;
	}
	if(ma.size()==1)for(int i=0;i<b;i++)ans+=mc[getmid(va[0],vb[i])]*a;
	else if(mb.size()==1)for(int i=0;i<a;i++)ans+=mc[getmid(va[i],vb[0])]*b;
	else if(mc.size()==1)for(int i=0;i<a;i++)ans+=mb[getnxt(va[i],vc[0])]*c;
	else{
		u=ma.begin(),t=ma.end();
		t--;
		Aa=u->F.S-t->F.S,Ba=t->F.F-u->F.F;
		Ca=Aa*(u->F.F)+Ba*(u->F.S);
		u=mb.begin(),t=mb.end();
		t--;
		Ab=u->F.S-t->F.S,Bb=t->F.F-u->F.F;
		Cb=Ab*(u->F.F)+Bb*(u->F.S);
		u=mc.begin(),t=mc.end();
		t--;
		Ac=u->F.S-t->F.S,Bc=t->F.F-u->F.F;
		Cc=Ac*(u->F.F)+Bc*(u->F.S);
		if(Aa==0){
			if(Ab==0){
				if(Ac==0){
					if(Cc*Bb*Ba*2==Ca*Bb*Bc+Cb*Ba*Bc)ans=allsame(va,vb,vc);
					else ans=0;
				}
				else ans=ABsame(va,vb,vc);
			}
			else if(Ac==0)ans=ACsame(va,vb,vc);
			else if(Ab*Bc==Bb*Ac)ans=ACsame(vb,va,vc);
			else {
				for(pair<pair<int,int>,long long int> i:mb){
					temp=intersect(Aa,Ba,Ca,Ac,Bc,Cc*2-Ac*i.F.F-Bc*i.F.S);
					ans+=ma[temp]*mc[getmid(temp,i.F)]*i.S;
				}
			}
		}
		else if(Ba==0){
			if(Bb==0){
				if(Bc==0){
					if(Cc*Aa*Ab*2==Ca*Ab*Ac+Cb*Aa*Ac)ans=allsame(va,vb,vc);
					else ans=0;
				}
				else ans=ABsame(va,vb,vc);
			}
			else if(Bc==0)ans=ACsame(va,vb,vc);
			else if(Ab*Bc==Bb*Ac)ans=ACsame(vb,va,vc);
			else{
				for(pair<pair<int,int>,long long int> i:mb){
					temp=intersect(Aa,Ba,Ca,Ac,Bc,Cc*2-Ac*i.F.F-Bc*i.F.S);
					ans+=ma[temp]*mc[getmid(temp,i.F)]*i.S;
				}
			}
		}
		else if(Ab==0){
			if(Ac==0)ans=ACsame(vb,va,vc);
			else if(Aa*Bc==Ac*Ba)ans=ACsame(va,vb,vc);
			else {
				for(pair<pair<int,int>,long long int> i:mb){
					temp=intersect(Aa,Ba,Ca,Ac,Bc,Cc*2-Ac*i.F.F-Bc*i.F.S);
					ans+=ma[temp]*mc[getmid(temp,i.F)]*i.S;
				}
			}
		}
		else if(Bb==0){
			if(Bc==0)ans=ACsame(vb,va,vc);
			else if(Aa*Bc==Ac*Ba)ans=ACsame(va,vb,vc);
			else{
				for(pair<pair<int,int>,long long int> i:mb){
					temp=intersect(Aa,Ba,Ca,Ac,Bc,Cc*2-Ac*i.F.F-Bc*i.F.S);
					ans+=ma[temp]*mc[getmid(temp,i.F)]*i.S;
				}
			}
		}
		else if(Aa*Bb==Ab*Ba){
			if(Ab*Bc==Bb*Ac){
				if(Cc*Ab*Aa*2==Ca*Ab*Ac+Cb*Aa*Ac)ans=allsame(va,vb,vc);
				else ans=0;
			}
			else ans=ABsame(va,vb,vc);
		}
		else if(Bb*Ac==Bc*Ab)ans=ACsame(vb,va,vc);
		else if(Aa*Bc==Ac*Ba)ans=ACsame(va,vb,vc);
		else{
			for(pair<pair<int,int>,long long int> i:mb){
				temp=intersect(Aa,Ba,Ca,Ac,Bc,Cc*2-Ac*i.F.F-Bc*i.F.S);
				ans+=ma[temp]*mc[getmid(temp,i.F)]*i.S;
			}
		}
	}
	printf("%lld\n",ans);
}