题目:https://www.acwing.com/problem/content/233/
题意:给你n个不同的数,让你选取一个四元组,gcd为1,让你求这样的四元组数量是多少
思路:我们单独直接去算肯定不行,正难反易,我们可以用总的减去其他gcd不是1的,也就是四个数同时有一个相同且不是1的因子,然后我们按gcd值分组
但是中间有很多分组其实有重复的值,比如 2,3 那么 6就是他们重复的,这个题不能n^2过,我们只能拆每个数的因子,然后用这些因子构造出其他与当前
数构造出不是1因子的个数
#include<bits/stdc++.h> #define ll long long #define mod 1000000007 #define maxn 100005 using namespace std; ll n,a[maxn],cnt; int vis[maxn]; int flag[maxn]; ll prime[maxn]; ll C(ll n,ll m){ return n*(n-1)*(n-2)*(n-3)/24; } void make(ll x){ cnt=0; for(int i=2;i*i<=x;i++){ if(x%i==0){ prime[cnt++]=i; while(x%i==0) x/=i; } } if(x>1) prime[cnt++]=x; for(int i=1;i<(1<<cnt);i++){ ll cur=1; ll num=0; for(int j=0;(i>>j)>0;j++){ if((i>>j)&1){ num++; cur*=prime[j]; } } vis[cur]++; flag[cur]=num; } } int main() { while(scanf("%lld",&n)!=EOF){ memset(vis,0,sizeof(vis)); memset(flag,0,sizeof(flag)); for(int i=0;i<n;i++){ scanf("%lld",&a[i]); make(a[i]); } ll sum=C(n,4); for(int i=2;i<=10000;i++){ if(flag[i]&1){ sum-=C(vis[i],4); } else{ sum+=C(vis[i],4); } } printf("%lld ",sum); } }