四元组统计
链接:https://www.luogu.com.cn/problem/P2714
原链接:https://www.acwing.com/problem/content/233/
题目描述:题目应该说的很清楚了。
题解:假如你按莫比乌斯那一套走的话令\(p_{i}\)表示\(i\)在数列中出现的次数你会发现会算重。而且由于莫比乌斯函数太玄学,貌似都无法容斥。
所以我们要换一种思路,考虑反演那一套:
令\(f_{x}\)表示\(\gcd=x\)的四元组个数,\(g_{x}\)表示\(x|\gcd\)的四元组个数。
则\(g_{x}=\sum_{x|i}f_{i}\),反演得\(f_{x}=\sum_{x|i}g_{i}μ({\frac{i}{x}})\)
由于\(g_{x}\)可以快速求,所以我们可以求出\(f_{x}\)。
#include<iostream>
#define N 30000
using namespace std;
long long res,t,n,F[30001],f[30001],miu[30001],a[30001];
bool prime[30001];
int main()
{
for (int i=1;i<=N;++i)
miu[i]=1;
for (int i=2;i<=N;++i)
if (!prime[i])
{
for (int j=i;j<=N;j+=i)
{
prime[j]=1;
miu[j]=-miu[j];
if ((j/i)%i==0)
miu[j]=0;
}
}
while (cin>>n)
{
res=0;
for (int i=1;i<=N;++i)
f[i]=F[i]=0;
for (int i=1;i<=n;++i)
{
cin>>a[i];
F[a[i]]++;
}
for (int i=1;i<=N;++i)
{
for (int j=i;j<=N;j+=i)
f[i]+=F[j];
f[i]=f[i]*(f[i]-1)*(f[i]-2)*(f[i]-3)/24;
}
for (int i=1;i<=N;++i)
res+=f[i]*miu[i];
cout<<res<<endl;
}
return 0;
}
本文来自博客园,作者:zhouhuanyi,转载请注明原文链接:https://www.cnblogs.com/zhouhuanyi/p/16983676.html

浙公网安备 33010602011771号