HDU-1796 How many integers can you find 容斥原理,细节

HDU-1796 How many integers can you find 容斥原理,细节

题意

给定一个(N) 和一个大小为(M) 的集合,集合元素为非负整数 ,求([1,n)) 内是集合里任意一个数的倍数的数字个数

[n leq 2^{31},m leq 10 ]

分析

因为要直接算(1-n) 中多少个数字是某个数的倍数是比较好算的,现在只不过是多个数,看到数据范围小于等于10应该比较好想到容斥

[ans = sum f(a_i) - sum f(lcm(a_i,a_j)) + sum f(lcm(a_i,a_j,a_k)).... ]

然后二进制枚举就完事了

注意点:范围是([1,n)) 所以是((n - 1) / res) 。 题目只说了非负整数 ,所以如果出现(0) 就麻烦了,干脆不读入

代码

vector<int> a;

int main() {
    int n, m;
    while (~scanf("%d%d", &n, &m)) {
        a.clear();
        int ans = 0;
        for (int i = 0; i < m; i++) {
            int x = readint();
            if(x) a.push_back(x);
        }
        m = a.size();
        for (int i = 1; i < (1 << m); i++) {
            int res = 1;
            int byte = 0;
            for (int j = 0; j < m; j++) {
                if ((1 << j) & i) byte++, res = Lcm(res, a[j]);
            }
            if (byte & 1) ans += (n - 1) / res;
            else ans -= (n - 1) / res;
        }
        Put(ans);
        puts("");
    }
}
原文地址:https://www.cnblogs.com/hznumqf/p/13596806.html