hdu 1796 hdu 4135 容斥原理

来源:互联网 发布:广电网络客服电话天津 编辑:程序博客网 时间:2024/06/05 01:23

hdu 1796 How many integers can you find

題意

給出一個數字n和一個整數集合S,問比n小的數中,共有多少個數可以被集合S中的若干元素整除。

思路

換個意思就是在[1,n1]中,有多少個數字是集合S中元素的倍數。對S中的元素k,我們可以知道在[1,n1]。存在(n1)/k個數是其的倍數。然後我們就可以對S數組進行容斥了。要注意的是在集合S中多個元素的倍數的集合的并,是他們lcm的倍數的集合。還有S中存在”0”元素,要先刪去。

code

#include <bits/stdc++.h>using namespace std;long long n, m;long long a[22];long long ans = 0;long long __lcm (int a, int b) {    return a / __gcd(a, b) * b;}long long _get (int _s) {    int _c = 0;    long long _r = 1;    for (int i=0; i<m; i++) {        if (((_s >> i) & 1) == 0) continue;        _c++;        _r = __lcm(_r, a[i]);    }    if (_c % 2 == 0) return -(n-1) / _r;    else return (n-1) / _r; }void _solve () {    ans = 0;    for (int _s = 1; _s < (1<<m); _s++) {        ans += _get(_s);    }    }int main () {    for (; scanf ("%I64d%I64d", &n, &m) == 2; ) {        for (int i=0; i<m; i++) {            scanf("%I64d", &a[i]);            if (a[i] == 0) {i--; m--;}        }        _solve();        printf ("%I64d\n", ans);    }    return 0;}

hdu 4135 Co-prime

題意

求[A, B]之間有多少個數字於N互素。
(1AB1015,1N109).

思路

對N進行素因子分解。得到素因子p[],在[A,B]中p[i]的倍數一定不是於N互素。於是我們對p[]容斥就行。

code

#include <bits/stdc++.h>using namespace std;long long a, b, n;long long ans = 0;long long _d[13];int _c;void _div() {    _c = 0;    memset(_d, 0, sizeof(_d));    for (int i=2; i*i <= n; i++) {        if (n % i != 0) continue;        _d[_c++] = (long long)i;        while (n % i == 0) n /= i;     }    if (n != 1) {        _d[_c++] = n;    }}long long _get(int _s) {    int _cnt = 0, _res = 1;    for (int i=0; i<_c; i++) {        if (((_s >> i) & 1) == 0) continue;        _cnt++;        _res *= _d[i];    }    if (_cnt % 2 == 1) return b/_res - (a - 1)/_res;    else return (a - 1)/_res - b/_res;}void _solve() {    _div();    ans = 0;    for (int _s=1; _s < (1<<_c); _s++) {        ans += _get(_s);     }    ans = b - a + 1L - ans; }int main() {    int T;    scanf ("%d", &T);    for (int cases = 1; cases <= T; cases++) {        scanf ("%I64d%I64d%I64d", &a, &b, &n);        _solve();        printf ("Case #%d: %I64d\n", cases, ans);    }    return 0;}
0 0