快速求popcount的和
前置知识
\(\text{popcount}(n)\) 表示将 \(n\) 转为二进制后的数中 \(1\) 的个数。
结论
\]
其中 $ \left [ (n>>(i-1))\text{&}1==1 \right ]$ 表示 \(n\) 转成二进制以后第 \(i\) 位是不是 \(0\)。
原理
首先我们需要知道这个东西:
__builtin_popcount(x)
可恶怎么又是 STL
他的作用就是求出 \(x\) 的 \(\text{popcount}\) 值,这个东西好像很快我们先把他当作 \(O(1)\) 的。
接下来我们考虑用 \(O(1)\) 的时间来求得
\]
的做法。
这里以 $ \left [ 0,2^{5}-1 \right ] $ 为例。
先把所有的数都给列出来。
然后我们可以看到最低位的规律。
依次向后走。
我们可以看到每一位里面都是一半是 \(0\),一半是 \(1\)。
因此我们可以得到下面的公式:
\]
下面以 \((11010110)_{2}=(214)_{10}\) 为例。
其第一位为 \(1\),所以我们直接计算 \((00000000)_{2}\text{~}(01111111)_{2}\) 的 \(\text{popcount}\) 和,也就是 \(0\times 2^{7}+7\times 2^{6}\)。
其第二位为 \(1\),所以我们直接计算 \((10000000)_{2}\text{~}(10111111)_{2}\) 的 \(\text{popcount}\) 和,也就是 \(1\times 2^{6}+6\times 2^{5}\)。
其第三位是 \(0\),对答案没有贡献。
其第四位为 \(1\),所以我们直接计算 \((11000000)_{2}\text{~}(11001111)_{2}\) 的 \(\text{popcount}\) 和,也就是 \(2\times 2^{4}+4\times 2^{3}\)。
其第五位是 \(0\),对答案没有贡献。
其第六位为 \(1\),所以我们直接计算 \((11010000)_{2}\text{~}(11010011)_{2}\) 的 \(\text{popcount}\) 和,也就是 \(3\times 2^{2}+2\times 2^{1}\)。
其第七位为 \(1\),所以我们直接计算 \((11010100)_{2}\text{~}(11010101)_{2}\) 的 \(\text{popcount}\) 和,也就是 \(4\times 2^{1}+1\times 2^{0}\)。
其第八位是 \(0\),对答案没有贡献。
但其实我们只需要处理 \([0,n)\) 这个区间分段即可。
最后再加上 \(\text{popcount}((11010110)_{2})=5\)。
最终结果就是:
\]
\]
\]
因为 \(\text{popcount}(0)=0\),所以统计不统计都可以。
代码
scanf("%d", &n);
long long tot = 0;
int cnt = 0;
int x = n;
while(x)
{
if(x & 1)
tot += (cnt * (1 << (cnt - 1))) + (1 << cnt) * __builtin_popcount(x >> 1);
x >>= 1;
cnt++;
}
tot += __builtin_popcount(n);
printf("%lld ", tot);
转载自:https://kaiserwilheim.github.io/OI/fast-popcnt-sum/
虽然是转载但是 \(\LaTeX\) 都是我自己打的QAQ
快速求popcount的和的更多相关文章
- 快速求n的质因子(数论)
快速求n的质因子 如何尽快地求出n的质因子呢?我们这里又涉及两个好的算法了! 第一个:用于每次只能求出一个数的质因子,适用于题目中给的n的个数不是很多,但是n又特别大的 #include<std ...
- 【GDOI 2011 DAY2 T3】零什么的最讨厌了 (快速求阶乘、中国剩余定理)
问题描述: 林记在做数学习题的时候,经常遇到这种情况:苦思冥想了很久终于把问题解出来,结果发现答案是0,久而久之林记在得到习题答案是0的时候就没有了做出一道难题的成就感.于是林记决定:以后出题,答案一 ...
- 快速求幂(Quick Exponentiation)
接触ACM没几天,向各路大神求教,听说ACM主要是研究算法,所以便开始了苦逼的算法学习之路.话不多说,RT所示,学习快速求幂. 在头文件<math.h>或是<cmath>中,d ...
- hdu 2814 快速求欧拉函数
/** 大意: 求[a,b] 之间 phi(a) + phi(a+1)...+ phi(b): 思路: 快速求欧拉函数 **/ #include <iostream> #include & ...
- NYOJ--102--次方求模(快速求幂取模)
次方求模 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 求a的b次方对c取余的值 输入 第一行输入一个整数n表示测试数据的组数(n<100)每组测试只有一 ...
- javascript中快速求数组的全部元素的相加之和
js中快速求数组的全部元素的相加之和: var arr = [1,2,3,4,5];var sum = eval(arr.join('+')); console.log(sum); 运行结果: 15
- HDU 2035 人见人爱A^B(二分求幂,快速求幂)
题意:求A的B次方的后三位数字 思路1:常规求幂,直接取余求解 代码: #include<iostream> #include<cstdio> using namespace ...
- 快速求排列C(m,n)加取模
快速求排列组合C(m,n)%mod 写在前面: 1. 为防止产生n和m的歧义,本博文一律默认n >= m 2. 本博文默认mod = 10^6+3 3. 本博文假设读者已知排列组合公式 C(m, ...
- 线性齐次递推式快速求第n项 学习笔记
定义 若数列 \(\{a_i\}\) 满足 \(a_n=\sum_{i=1}^kf_i \times a_{n-i}\) ,则该数列为 k 阶齐次线性递推数列 可以利用多项式的知识做到 \(O(k\l ...
- Quick Pow: 如何快速求幂
今天讲个有趣的算法:如何快速求 \(n^m\),其中 n 和 m 都是整数. 为方便起见,此处假设 m >= 0,对于 m < 0 的情况,求出 \(n^{|m|}\) 后再取倒数即可. ...
随机推荐
- nextcloud file location
- 读书笔记<<世界是部金融史>>
1.权力只对来源负责.权力只会对其来源负责--孟德斯鸠<论法的精神> 2.能违反的是纪律,不能违反的是规律.人自然要遵从人性规律. 3.在金融市场中有一个法则,如果市场认为一件事是真的,那 ...
- 两步解决macbook电池不充电
问题描述: 1.电源适配器是冷的,判断并没有充电,更换拔插笔记本的不同TypeC插口问题依然.(怀疑适配器坏了,但心想Apple质量一个适配器不至于那么不抗用) 2.偶尔能开起来机,则显示电源3%,瞬 ...
- Centos7安装nodejs(npm)
执行命令: 设置yum安装源> curl --silent --location https://rpm.nodesource.com/setup_14.x | sudo bash (14是大的 ...
- MacOS ssh config 配置
Host 别名 #password 注释,保存密码 HostName IP User 服务器账号#root Port 端口 IdentityFile ~/.ssh/id_rsa #指定密钥 Remot ...
- vue 缓存后台获取的token
代码 localStorage.setItem("token",res.data.data);// 用localStorage缓存token值
- 基于Quartz.Net通过反射进行任务调度
通过反射加载任务调度 需求: 因为有些任务需要进行各种定时操作,因此将 Quartz.Net 简单封装了一下使用: 希望通过上传 dll 来进行每个任务的调度,所以写了个反射调度示例: Program ...
- 使用 Vue 3 时应避免的 10 个错误
Vue 3已经稳定了相当长一段时间了.许多代码库都在生产环境中使用它,其他人最终都将不得不迁移到Vue 3.我现在有机会使用它并记录了我的错误,下面这些错误你可能想要避免. 使用Reactive声明原 ...
- 笔精墨妙,妙手丹青,微软开源可视化版本的ChatGPT:Visual ChatGPT,人工智能AI聊天发图片,Python3.10实现
说时迟那时快,微软第一时间发布开源库Visual ChatGPT,把 ChatGPT 的人工智能AI能力和Stable Diffusion以及ControlNet进行了整合.常常被互联网人挂在嘴边的& ...
- RPA的市场需求
最基本的RPA软件机器人定义:机器人通过记录员工在电脑桌面上的操作行为,将业务处理规则和操作行为记录下来,并模拟人的方式在电脑上自动执行一系列特定的工作流程.采用RPA软件机器人解决方案,快速实施,快 ...