当前位置: 首页 > news >正文

UVa 12670 Counting Ones

题目描述

给定两个整数 AAABBB1≤A≤B≤10161 \leq A \leq B \leq 10^{16}1AB1016),要求计算从 AAABBB(包含两端)的所有整数的二进制表示中,数字 111 出现的总次数。

例如:

  • 输入:222 121212
  • 输出:212121

数据范围AAABBB 最大可达 101610^{16}1016,因此不能直接遍历统计,需要高效的数学方法。


题目分析

这是一个典型的数位统计问题。由于数据范围非常大,直接遍历每个数并统计其二进制中 111 的个数是不可行的(时间复杂度为 O(B−A)O(B-A)O(BA),会超时)。

我们需要找到一种方法,能够快速计算从 111nnn 的所有数的二进制中 111 的个数总和。


解题思路

关键思路

定义函数:
countOnes(n)=从 1 到 n 的所有数的二进制表示中 1 的个数总和 \text{countOnes}(n) = \text{从 1 到 n 的所有数的二进制表示中 1 的个数总和} countOnes(n)= 1  n 的所有数的二进制表示中 1 的个数总和
那么答案就是:
答案=countOnes(B)−countOnes(A−1) \text{答案} = \text{countOnes}(B) - \text{countOnes}(A-1) 答案=countOnes(B)countOnes(A1)

如何计算 countOnes(n)\text{countOnes}(n)countOnes(n)

我们按二进制位分别计算每一位上 111 出现的次数,然后求和。

对于第 kkk 位(从最低位 000 开始):

  • 该位的循环周期是 2k+12^{k+1}2k+1(即 000111 交替的周期长度)
  • 每个完整周期中,该位为 111 的次数是 2k2^k2k
  • 设完整周期数为 ⌊n+12k+1⌋\lfloor \frac{n+1}{2^{k+1}} \rfloor2k+1n+1,那么完整周期贡献的 111 的个数为:
    完整周期贡献=⌊n+12k+1⌋×2k \text{完整周期贡献} = \left\lfloor \frac{n+1}{2^{k+1}} \right\rfloor \times 2^k 完整周期贡献=2k+1n+1×2k
  • 剩余部分(不完整的周期):
    剩余长度 r=(n+1) mod 2k+1r = (n+1) \bmod 2^{k+1}r=(n+1)mod2k+1
    如果 r>2kr > 2^kr>2k,则多出的 111 的个数为 r−2kr - 2^kr2k,否则为 000

因此:
第 k 位贡献=⌊n+12k+1⌋×2k+max⁡(0,(n+1) mod 2k+1−2k) \text{第 k 位贡献} = \left\lfloor \frac{n+1}{2^{k+1}} \right\rfloor \times 2^k + \max(0, (n+1) \bmod 2^{k+1} - 2^k)  k 位贡献=2k+1n+1×2k+max(0,(n+1)mod2k+12k)

对所有位 kkk000⌊log⁡2n⌋\lfloor \log_2 n \rfloorlog2n 求和,就是 countOnes(n)\text{countOnes}(n)countOnes(n)


参考代码

// Counting Ones
// UVa ID: 12670
// Verdict: Accepted
// Submission Date: 2025-10-31
// UVa Run Time: 0.000s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include <iostream>using namespace std;typedef unsigned long long ull;// 计算从 1 到 n 的所有数的二进制中 1 的个数总和
ull countOnes(ull n) {ull total = 0; // 存储总个数ull currentPower = 1; // 2^kull nextPower = 2; // 2^(k+1)// 遍历每一位while (currentPower <= n) {// 完整周期的贡献total += ((n + 1) / nextPower) * currentPower;// 不完整周期的贡献ull remainder = (n + 1) % nextPower;if (remainder > currentPower) {total += remainder - currentPower;}// 移动到下一位currentPower <<= 1;nextPower <<= 1;}return total;
}int main() {ull A, B;// 处理多组测试用例while (cin >> A >> B) {// 计算 [A, B] 区间的 1 的个数 = countOnes(B) - countOnes(A-1)ull result = countOnes(B) - countOnes(A - 1);cout << result << endl;}return 0;
}
http://www.dtcms.com/a/553428.html

相关文章:

  • C++17(新特性)
  • 韩国风网站什么网站有做册子版
  • day58-Shell编程(第四部分)
  • 用AI写了一个文档拼音标注工具 中文+拼音一键生成
  • 做网站还有意义同样是div 怎么有些网站收录少 有些多
  • 企必搜做网站做国际物流在哪些网站找客户
  • 移动端适配完全指南:从基础到最佳实践
  • 使用JMeter进行API性能压测(执行篇)
  • IntelliJ IDEA 远程调试(Remote Debugging)教程
  • 网站服务器++免费做电子手抄报的网站
  • 单页网站的优点网络公司是做什么的?
  • 阿瓦隆 Q 90T矿机:低功耗高效挖矿,是否值得选择?
  • 印度实时股票数据源接口对接文档-IPO新股、k线数据
  • HTTPS接口国密安全设计(含防重放设计)
  • 网站设计公司(信科网络)中国制造网外贸平台怎么注册
  • 网站模版如何去除title版权信息499元做网站
  • 武进建设局网站首页胖鼠wordpress
  • 机器学习第一阶段
  • Linux内核RDMA用户态内存映射机制深度解析:零拷贝高性能的基石
  • 组态软件和实时数据库区别大吗?
  • SpringBoot】Spring Boot 项目的打包配置
  • 递归专题5 - FloodFill算法专题
  • 系统架构设计师论文-论软件架构的复用
  • 沙市做网站weiswordwordpress微信登录设置
  • 理解MySQL的原理
  • Mac通过命令行开启ssh服务
  • 哈尔滨有哪些做网站的公司站长工具seo综合查询问题
  • 珠海做网站的wordpress 写作
  • 【计算机基础】之核心架构
  • 临西网站建设公司公司核名查询官网