1. 程式人生 > 實用技巧 >HDU-1796 How many integers can you find 容斥原理,細節

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("");
    }
}