容斥原理

容斥原理

容斥原理就是求几个集合的并集的元素个数的公式。换句话说就是整体韦恩图的元素个数。

三个集合的容斥原理

能被整除的数

分析题意是求所有的集合交集的基数,可利用容斥原理。

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;

const int M = 20;
int p[M];

int main(){
    int n, m; cin >> n >> m;
    for (int i = 0; i < m; i ++) cin >> p[i];
    int res = 0;
    for (int i = 1; i < 1 << m; i ++){ // 所有项 二进制上的位来判断选了那一项
        int t = 1, cnt = 0;    // t 是乘积,表示 p_x * p_y、cnt 是计数选了多少个集合,便于判断符号 
        for (int j = 0; j < m; j ++){    // 通过判断所有位来计算到底选了那一位
            if (i >> j & 1){
               if ((LL)t * p[j] > n){   // 乘过头了
                   t = -1;
                   break;
               }
               t *= p[j];
               cnt ++;
            }
        }
        if (t != -1){    
            if (cnt % 2) res += n / t;
            else res -= n / t;
        }
    }
    cout << res << endl;
}

时间复杂度

两层 for 循环可得时间复杂度 $$O(m * 2^m)$$

2-Letter Strings

最后更新于