题意:
给出n个数,求这个n个数满足{gcd(a,b)=1&&gcd(a,c)=1&&gcd(b,c)=1||gcd(a,b)!=1&&gcd(a,c)!=1&&gcd(b,c)!=1}这个条件的三元组个数。
题解:
这里用到了同色三角形的模型,先说下同色三角形。
同色三角形:
假设平面上有n个点,现在有些点被染上黑色,而有些则被染上白色。对于平面上的三个点连线可以组成三角形,总的三角形个数C(n,3),同色三角形的个数=总数-非同色三角形的个数。
非同色三角形个数设为sun,那么sum=SUM{sigma(Xi*Yi)}/2。Xi表示i点与能与多少个黑色点连接,Yi同理(白色)。那么Yi=(n-Xi)。
这题就是计算同色三角形的个数。
那么用总数C(n,3)-SUM{只有一对互质,只有两对互质} 那么SUM=sum{(k-1)*(n-k)}/2;
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> #define B(x) (1<<(x)) using namespace std; typedef long long ll; typedef __int64 LL; void cmax(int &a,int b){ if(b>a)a=b; } void cmin(int &a,int b){ if(b<a)a=b; } void cmax(ll &a,ll b){ if(b>a)a=b; } void cmin(ll &a,ll b){ if(b<a)a=b; } void add(int &a,int b,int mod){ a=(a+b)%mod; } void add(ll &a,ll b,ll mod){ a=(a+b)%mod; } void add(int &a,int b){ a+=b; } void add(ll &a,ll b){ a+=b; } const int oo=0x3f3f3f3f; const ll MOD=1000000007; const int maxn=110000; int a[maxn],n; int num[maxn]; int fac[100],cnt; void get_fac(int n){ cnt=0; for(int i=2;i*i<=n;i++){ if(n%i==0){ fac[cnt++]=i; while(n%i==0) n/=i; } } if(n>1&&n!=fac[cnt-1])fac[cnt++]=n; } void Init(){ scanf("%d",&n); memset(num,0,sizeof num); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); get_fac(a[i]); int full=B(cnt)-1; for(int s=1;s<=full;s++){ int res=1; for(int j=0;j<cnt;j++){ if(s&B(j)){ res*=fac[j]; } } num[res]++; } } } void solve(){ ll ans=0; for(int i=1;i<=n;i++){ get_fac(a[i]); int full=B(cnt)-1; ll t=0; for(int s=1;s<=full;s++){ int res=1,bit=0; for(int j=0;j<cnt;j++){ if(s&B(j)){ res*=fac[j]; bit++; } } if(bit&1) t+=num[res]; else t-=num[res]; } if(t==0)continue; ans+=(t-1)*(n-t); } ans=(ll)n*(n-1)*(n-2)/6-ans/2; cout<<ans<<endl; } int main(){ int T; scanf("%d",&T); while(T--){ Init(); solve(); } return 0; }