题目: 求一个数组里面,gcd(a, b, c, d) = 1的四元组的组数。
容斥。 如果直接正向容斥,状态太多。 所以我们考虑对每一个数进行分解。 记录一下这个数可以被哪些数整除。这里利用的是唯一分解定理:任意一个数都只能被拆成一种质因子相乘的形式。
code:
#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;
}