题意:
给你一个长度为n的序列,让你求序列的最大公约数为1的子序列数目为多少?
思路:
莫比乌斯反演
首先统计一下该序列有什么数,个数为多少。
然后求莫比乌斯函数。
统计有i为因子的数有x。
根据x求都有该因子的序列有 ( )个
根据莫比乌斯函数判断该序列数是加上还是减去.
最后得出结果.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=1e9+7;
const int N=2e5+5;
ll x,mu[N], ma[N];
ll dp[N], prime[N], ji=0, pa[N];
int main()
{
int n;
ll m=0;
cin>>n;
dp[0]=1;
for(int i=1;i<=n;i++)
{
dp[i]=dp[i-1]*2%inf;
}
for(int i=1;i<=n;i++)
{
cin>>x;
m=max(m,x);
ma[x]++;
}
mu[1]=1;
pa[1]=1;
for(ll i=2;i<=m;i++)
{
if(!pa[i])
{
prime[ji++]=i;
mu[i]=-1;
}
for(int j=0;j<ji;j++)
{
if(i*prime[j]>m)
{
break;
}
pa[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
else
{
mu[i*prime[j]]=-mu[i];
}
}
}
ll ans=0;
for(int i=1;i<=m;i++)
{
ll s=0;
for(int j=1;j*i<=m;j++)
{
s+=ma[i*j];
}
ans=(ans+(mu[i]*(dp[s]-1)%inf+inf)%inf)%inf;
}
cout<<ans<<'\n';
return 0;
}

京公网安备 11010502036488号