//题意,给出n个数,问有多少组(a,b,c,d)公约数为1,注意并不一定两两互质!因为不一定两两都互质,那么从相反的方向着手比较方便!即先统计出(a,b,c,d)公约数>1的对数,然后用总数减去即可!
容斥原理应用,以2为因子的数有a个,3为因子 的数有b个,6为因子的数有c个,n个数不互质的四元组个数为C(4,a)+C(4,b)-C(4,c) (含奇数个素因子的加,偶数个素因子的减),下面就是统计出2,3,5这些因子的倍数的个数,对C(4,a)容斥!
就是因为不一定满足两两互斥的条件,因此要考虑逆着求,然后每个素因子以及他们的积是加还是减是固定的,因此用它容斥就可以了!
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int n;
int a[10010];
bool is[10010];
vector<int> pr;
void div(int x){
pr.clear();
for(int i=2; i*i<=x; i++){
if(x % i == 0) pr.push_back(i);
while(x % i == 0) x /= i;
}
if( x > 1 ) pr.push_back(x);
}
int Count[10010];
int num[10010];
void solve(int x){
div(x);
int size = pr.size();
int all = (1<<size);
for(int i=1; i<all; i++){
long long t = 1;
long long ci = 0;
for(int j=0; j < size; j++){
if(i&(1<<j)){
t *= pr[j];
ci++;
}
}
Count[t]++;
num[t] = ci;
}
}
long long c(long long a){
return a*(a-1)*(a-2)*(a-3)/24;
}
int main(){
while(cin>>n){
memset(Count, 0, sizeof(Count));
for(int i=1; i<=n; i++) scanf("%d", &a[i]), solve(a[i]);
long long res = 0;
for(int i=1; i<=10000; i++){
if(Count[i]){
if(num[i]&1) res += c(Count[i]);
else res -= c(Count[i]);
}
}
res = c(n) - res;
printf("%lld\n", res);
}
return 0;
}