题目链接:
https://www.acwing.com/problem/content/233/
题意:
给定你一个由N个不同整数构成的整数序列,从这个整数序列中选出4个数,使得这4个数的唯一公约数为1。
求满足条件的四元组的个数。
输入格式
输入中包含多组测试用例。
每个测试用例占据两行,第一行包含整数N。
第二行包含N个用空格隔开的整数(均不超过10000),表示完整的整数序列。
输出格式
每个测试用例输出一个结果,每个结果占一行。
数据范围
1≤N≤10000
输入样例:
4
2 3 4 5
4
2 4 6 8
7
2 3 4 5 7 6 8
输出样例:
1
0
34
题解:
参考博客:https://www.cnblogs.com/lmjer/p/9325754.html
算出不互质四元组的个数,再用总数减去。
预处理一下C(n,4)
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn=10005;
ll f[maxn];
int prime[maxn];
int cnt[maxn],num[maxn];
int n;
void init(){
for(ll i=4;i<maxn;i++) f[i]=i*(i-1)*(i-2)*(i-3)/24;
}
void ff(int x){
int tot=0;
for(int i=2;i*i<=x;i++){
if(x%i==0){
prime[tot++]=i;
while(x%i==0) x/=i;
}
}
if(x>1) prime[tot++]=x;
for(int i=1;i<(1<<tot);i++){
int k=1,sum=0;
for(int j=0;j<tot;j++){
if(i>>j&1){
k*=prime[j];
sum++;
}
}
cnt[k]++;
num[k]=sum;
}
}
int main(){
init();
while(scanf("%d",&n)!=EOF){
memset(cnt,0,sizeof cnt);
for(int i=0;i<n;i++){
int x;
scanf("%d",&x);
ff(x);
}
ll ans=f[n];
for(int i=2;i<maxn;i++){
if(cnt[i]>=4){
if(num[i]&1) ans-=f[cnt[i]];
else ans+=f[cnt[i]];
}
}
printf("%lld\n",ans);
}
return 0;
}