题目链接:Coprime
题面:
1 5 1 3 9 10 2
4
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; bool status[100010]; int factor[100010][8]; int store[100010],cnt[100010]; long long ans[100010],res; int one_amount[300]; int refl[300][8]; int cal[8]; void prep() { memset(refl,0,sizeof(refl)); int cont=0,temp; for(int i=0;i<256;i++) { temp=i; one_amount[i]=cont=0; while(temp) { if(temp%2) { one_amount[i]++; refl[i][cont]=1; } cont++; temp/=2; } } } bool is_prime(int a) { if(a<=3)return true; int x=sqrt(1.0*a); for(int i=2;i<=x;i++) { if(a%i==0) return false; } return true; } long long C(int x,int y) { long long res=1; for(int i=1;i<=x;i++) { res=res*(y-i+1)/i; } return res; } int main() { int t,n,p,tmp; long long temp; scanf("%d",&t); prep(); while(t--) { res=0; memset(status,0,sizeof(status)); memset(factor,0,sizeof(factor)); memset(cnt,0,sizeof(cnt)); memset(ans,0,sizeof(ans)); scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&store[i]); for(int i=0;i<n;i++) status[store[i]]=1; for(int i=2;i<=100000;i++) { if(is_prime(i)) { for(int j=i;j<=100000;j+=i) { if(status[j]) { cnt[i]++; } p=0; while(factor[j][p]) { p++; } factor[j][p]=i; } } else { for(int j=i;j<=100000;j+=i) { if(status[j]) { cnt[i]++; } } } } for(int i=0;i<n;i++) { tmp=store[i]; p=0; while(factor[tmp][p]) { cal[p]=factor[tmp][p]; p++; } if(p==0) { ans[i]=0; continue; } tmp=1<<p; for(int j=1;j<tmp;j++) { temp=1; for(int k=0;k<p;k++) { if(refl[j][k]) { temp=temp*cal[k]; } } if(one_amount[j]%2) ans[i]+=cnt[temp]; else ans[i]-=cnt[temp]; } ans[i]-=1; } for(int i=0;i<n;i++) { res+=(ans[i]*(n-ans[i]-1)); } res/=2; printf("%I64d\n",C(3,n)-res); } return 0; }