Coprime Subsequences

Coprime Subsequences

https://ac.nowcoder.com/acm/problem/112055

题意:
给你一个长度为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;
}
每日一题题解 文章被收录于专栏

写题解

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务