hdu 1796

在 $< n$ 的数中能被 $x$ 整除的数的个数为 $(n - 1) / x$
在 $< n$ 的数中能被 $x, y$ 整除的数的个数为 $(n - 1) / lcm(x, y)$
......

考虑容斥
$Answer = \sum_{i = 1} ^ {tot} (-1) ^ {(i + 1)} (n - 1) / (A 集合中任意 i 个数的 lcm)$

#include <iostream>
#include <cstdio>

using namespace std;
const int N = 30;

int A[N], n, m;
int ans, tot;

int Gcd(int a, int b) {return b == 0 ? a : Gcd(b, a % b);}

void Dfs(int pos, int pre_lcm, int k) {
    for(int i = pos + 1; i <= tot; i ++) {
        int lcm = pre_lcm / Gcd(pre_lcm, A[i]) * A[i];
        if(k & 1) ans += (n - 1) / lcm;
        else ans -= (n - 1) / lcm;
        Dfs(i, lcm, k + 1);
    }
}

int main() {
    while(scanf("%d%d", &n, &m) == 2) {
        ans = 0, tot = 0;
        for(int i = 1; i <= m; i ++) {
            int x; scanf("%d", &x);
            if(x > 0 && x < n) A[++ tot] = x;
        }
        Dfs(0, 1, 1);
        cout << ans << "\n";    
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/shandongs1/p/9516357.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值