题目
给定一个长度为(n)的序列(a),
求
[sum_{i=1}^nsum_{j=i+1}^nsum_{k=j+1}^nsum_{l=k+1}^n[gcd(a_i,a_j,a_k,a_l)==1]
]
分析
显然不能直接求出来,考虑容斥,
即用最大公约数为1的倍数的情况减去最大公约数不为1的情况
后面这一坨显然可以一直容斥,那么首先统计出每个数字出现的次数,
枚举倍数可以算出每个数字及它们的倍数出现的次数,
那么最大公约数为(x)或(x)的倍数的情况也就是(C_x^4)
时间复杂度(O(nlog n))
代码
#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef long long lll;
const int N=10001;
lll c[N]; int n;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(lll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
signed main(){
while (scanf("%d",&n)==1){
for (rr int i=1;i<N;++i) c[i]=0;
for (rr int i=1;i<=n;++i) ++c[iut()];
for (rr int i=1;i<N;++i)
for (rr int j=i<<1;j<N;j+=i) c[i]+=c[j];
for (rr int i=N-1;i;--i){
c[i]=c[i]*(c[i]-1)*(c[i]-2)*(c[i]-3)/24;
for (rr int j=i<<1;j<N;j+=i) c[i]-=c[j];
}
print(c[1]),putchar(10);
}
}