题意

给你n个数让你从中挑选一个非空子序列,使得子序列

问有多少个这样的非空子集

解析

我太菜了理解了好久这个容斥

首先来说就是正着求我们不好求 那么我们就去反过来求 把所有的 减去不等于1的

那么来分析一下有哪些不等于1的情况

简单来说就是有两个以上的数字他们有着一个相同的因子,那个因子就可以是

比如3 6 15 就有一个相同的因子3 所以他们这里就有个非空子序列

所以我们只要找到所有的这个 然后用总的减去不等于1的

我们统计每一个的因子

即计算这些数中有多少个数字包含因子

然后我们可以求出公约数为的序列数就等于

为什么要减去 因为我们在计算有多少个数字包含的时候,也给的里面增加了一个,先看代码 然后在代码里再解释这个

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; typedef unsigned long long ull; typedef long double ld;
const ll MOD = 1e9 + 7;

const int N = 1e5 + 7;
const int INF = 0x3f3f3f3f;

ll n , m;
ll p[N];
int cnt[N];
int a[N];

int main(void){
    cin>>n;
    p[0] = 1;
    for(int i = 1 ; i <= n ; ++i){
        p[i] = (p[i - 1] << 1) % MOD;
        int x ;
        cin>>x;
        for(int j = 1 ; j * j <= x ; ++j){
            if(x % j == 0){
                cnt[j]++;
                if(j * j == x)  continue;
                cnt[x / j]++;
            }
        }
    }
    for(int i = 1 ; i < N - 7; ++i){
        a[i] = (p[cnt[i]] - 1) % MOD;
    }
    for(int i = N - 7 ; i >= 1 ; --i){
        for(int j = i + i ; j <= N -7 ; j += i){
            a[i] = (a[i] - a[j] + MOD) % MOD;
        }
    }

    cout<<a[1]<<endl;
    return 0;
}

看代码就能看到

举例

6

1 2 3 4 5 6

我们在统计6的时候 给2也加上了一个 但是这个明显是用不了的 所以要减去