codeforces 803F Coprime Subsequences (容斥原理)

来源:互联网 发布:瞻博网络 上海 电话 编辑:程序博客网 时间:2024/06/05 06:15

题目原文:http://codeforces.com/problemset/problem/803/F

F. Coprime Subsequences

Let's call a non-empty sequence of positive integersa1, a2...akcoprime if the greatest common divisor of all elements of this sequence is equal to 1.

Given an arraya consisting ofn positive integers, find the number of itscoprime 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 are3 different subsequences:[1],[1] and[1, 1].

Input

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

The second line containsn integer numbersa1, a2...an (1 ≤ ai ≤ 100000).

Output

Print the number ofcoprime subsequences ofa modulo109 + 7.


题目大意:有 n 个数,让你找出其中互素的序列有多少个。


解题思路:可以很容易的到有某个约数的数字有多少个,这样的话就可以得到一个有约数 d 的集合。这个集合总共有2^d - 1个非空子集。问题在于这些集合很多是重复的,我们希望每个集合都表示最大公约数是 d 的集合,所以需要用到容斥原理,方法其实也很每一个子集的最大公约数了。


AC代码:

/*    @Author: wchhlbt    @Date:   2017/4/28*/#include <bits/stdc++.h>#define Fori(x) for(int i=0;i<x;i++)#define Forj(x) for(int j=0;j<x;j++)#define maxn 100007#define inf 0x3f3f3f3f#define ONES(x) __builtin_popcount(x)using namespace std;typedef long long ll ;const double eps =1e-8;const int mod = 1000000007;typedef pair<int, int> P;const double PI = acos(-1.0);int dx[4] = {0,0,1,-1};int dy[4] = {1,-1,0,0};int h[maxn];ll f[maxn];const int o = 100000;ll quickpow(ll m,ll n,ll k)     // return m^n % k{    ll b = 1;    m = m%k;    while (n > 0)    {          if (n & 1)             b = (b*m)%k;          n = n >> 1 ;          m = (m*m)%k;    }    return b;}int main(){    //freopen("test.txt","r",stdin);    int n,m;    scanf("%d",&n);    while(n--){        scanf("%d",&m);        for(int i = 1; i*i<=m; i++){            if(m%i==0){                h[i]++;                if(i*i!=m)                    h[m/i]++;            }        }    }    for(int i = 1; i<=o; i++)        f[i] = quickpow(2,h[i],mod) - 1;    for(int i = o; i; i--){        for(int j = i+i; j<=o; j+=i){            f[i] = ( f[i] - f[j] + mod )%mod;        }    }    cout << f[1] << endl;    return 0;}

0 0
原创粉丝点击