cf Educational Codeforces Round 20 F. Coprime Subsequences

来源:互联网 发布:英氏童装加盟 知乎 编辑:程序博客网 时间:2024/06/06 07:05

原题:
F. Coprime Subsequences
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Let’s call a non-empty sequence of positive integers a1, a2… ak coprime if the greatest common divisor of all elements of this sequence is equal to 1.

Given an array a consisting of n positive integers, find the number of its coprime subsequences. Since the answer may be very large, print it modulo 109 + 7.

Note that two subsequences are considered different if chosen indices are different. For example, in the array [1, 1] there are 3 different subsequences: [1], [1] and [1, 1].
Input

The first line contains one integer number n (1 ≤ n ≤ 100000).

The second line contains n integer numbers a1, a2… an (1 ≤ ai ≤ 100000).
Output

Print the number of coprime subsequences of a modulo 109 + 7.
Examples
Input

3
1 2 3

Output

5

Input

4
1 1 1 1

Output

15

Input

7
1 3 5 15 3 105 35

Output

100

Note

In the first example coprime subsequences are:

11, 21, 31, 2, 32, 3 

In the second example all subsequences are coprime.
中文:
给你一个序列,让你找出这个序列的所有子序列,这些子序列的要求最大公约数是1.

#include <bits/stdc++.h>using namespace std;typedef long long ll;const ll maxn=100001;const ll mod=1e9+7;ll mu[maxn],prime[maxn],mark[maxn];ll ind[maxn];ll pow2[maxn];void Mobius(){    mu[1]=1;    for(int i=2;i<maxn;i++)    {        if(!mark[i]){prime[++*prime]=i;mu[i]=-1;}        for(int j=1;i*prime[j]<maxn;j++)        {            mark[i*prime[j]]=1;            if(i%prime[j]==0)break;            mu[i*prime[j]]=-mu[i];        }    }}int main(){    ios::sync_with_stdio(false);    pow2[0]=1;    for(int i=1;i<maxn;i++)    {        pow2[i]=(pow2[i-1]*2)%mod;    }    Mobius();    int n;    while(cin>>n)    {        memset(ind,0,sizeof(ind));        for(int i=1;i<=n;i++)        {            int res;            cin>>res;            for(int j=1;j*j<=res;j++)            {                if(res%j==0)                {                    ind[j]++;                    if(res/j!=j)                    {                        ind[res/j]++;                    }                }            }        }        ll ans=0;        for(int i=1;i<maxn;i++)        {            ans=(ans+(pow2[ind[i]]-1)*mu[i])%mod;        }        cout<<(ans+mod)%mod<<endl;    }    return 0;}

思路:

使用容斥原理。
一共有n个数,那么n个数含有由的非空子集的个数是2^n-1个子集。
假设所有这n个数有因子x1,x2,x3...xk (不是素因子)
那么减去包含因子x1的集合个数,再减去包含x2 的集合个数,在加上包含因子x1x2 的集合个数,因为容斥原理当中多减去的公共集合部分要重新加上。

例如
7
1 3 5 15 3 105 35

一共7个数,所有共有2^7-1个子序列
因子含3的数有 3 15 3 105 ,共4个。那么这4个数能形成的公因子为3的子序列的个数是2^4-1个。
设seq(i)为含有因子i的数的个数

那个,样例的结果就是
2^7-1-(seq(2)^2-1)-(seq(3)^2-1)-(seq(5)^2-1)+(seq(2* 3)^2-1)+(seq(2* 5)^2-1)+(seq(3 * 5)^2-1)-(seq(2* 3 * 5)^2-1)-(seq(7)^2-1)+(seq(5 7)^2-1)+(seq(7 *3)^2-1)-(seq(3 5 * 7)^2-1)

利用莫比乌斯函数mu[i]的性质,即可得到上面结果。

原创粉丝点击