火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

__builtin_popcount

作者: 作者的头像   huolong , 时间:2026-07-26 15:13:33 , 所有人可见, 阅读  34

用枚举子集 + __builtin_popcount 求 1~1000 中能被 2、3、5 整除的数的个数思路 因子:2、3、5,共 3 个,用3 位二进制表示子集 子集共 8 个:000 ~ 111 对每个子集:

用 __builtin_popcount(mask) 求二进制中 1 的个数,确定容斥符号:偶数个因子加,奇数个减 求子集对应数的最小公倍数 LCM

计算 1~1000 内能被 LCM 整除的数的个数:1000 / lcm

最后按容斥累加得到答案

C++ 代码cpp运行

#include <iostream>
#include <algorithm> // __gcd
using namespace std;

int lcm(int a, int b) {
    return a / __gcd(a, b) * b;
}

int main() {
    int d[] = {2, 3, 5};
    int n = 3;
    int ans = 0;

    // 枚举所有子集 mask: 0 ~ 2^n - 1
    for (int mask = 1; mask < (1 << n); mask++) {
        int cnt = __builtin_popcount(mask); // 子集元素个数
        int cur_lcm = 1;

        for (int i = 0; i < n; i++) {
            if (mask & (1 << i)) {
                cur_lcm = lcm(cur_lcm, d[i]);
            }
        }

        int num = 1000 / cur_lcm;
        if (cnt % 2 == 1) ans += num;
        else ans -= num;
    }

    cout << ans << endl;
    return 0;
}

运行结果733 简要说明 mask = 001(1) → {2} mask = 010(2) → {3} mask = 100(4) → {5} mask = 011(3) → {2,3} → LCM=6 mask = 101(5) → {2,5} → LCM=10 mask = 110(6) → {3,5} → LCM=15 mask = 111(7) → {2,3,5} → LCM=30 容斥公式:

$ (ans = \left\lfloor\frac{1000}{2}\right\rfloor+\left\lfloor\frac{1000}{3}\right\rfloor+\left\lfloor\frac{1000}{5}\right\rfloor -\left\lfloor\frac{1000}{6}\right\rfloor-\left\lfloor\frac{1000}{10}\right\rfloor-\left\lfloor\frac{1000}{15}\right\rfloor +\left\lfloor\frac{1000}{30}\right\rfloor) $

结果 = 733

挑战题目:765. 能被整除的数

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码