容斥搞出 gcd 不是 \(1\) 的四元组个数。
参考
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
int n, cnt[10005], num[10005], uu, fac[35], din;
ll ans;
void div(int x){
for(int i=2; i*i<=x; i++)
if(x%i==0){
fac[din++] = i;
while(x%i==0) x /= i;
}
if(x>1) fac[din++] = x;
}
void cal(){
din = 0;
scanf("%d", &uu);
div(uu);
for(int i=1; i<(1<<din); i++){
int tmp=1, qwq=0;
for(int j=0; j<din; j++)
if(i&(1<<j)){
tmp *= fac[j];
qwq++;
}
cnt[tmp]++;
num[tmp] = qwq;
}
}
ll C(int x){
return (ll)(x-3)*(x-2)*(x-1)*x/24;
}
int main(){
while(scanf("%d", &n)!=EOF){
ans = 0;
memset(cnt, 0, sizeof(cnt));
memset(num, 0, sizeof(num));
for(int i=1; i<=n; i++)
cal();
for(int i=2; i<=10000; i++){
if(num[i]&1) ans += C(cnt[i]);
else ans -= C(cnt[i]);
}
printf("%lld\n", C(n)-ans);
}
return 0;
}