小技巧,计算一个十进制整数在二进制下“1”的个数
在写百度之星的时候遇到这个困难,要查看被压缩的状态里,有几个已处理的对象。c++里可以用一个函数来解决,但是运算复杂度高,在多组数据时没有优势,而且在高中竞赛中也禁止使用。
所以我写了一个预处理,处理出数据范围内所有数在二进制下有几个1,并存进数组里。
想法
ans->0
对每个数都mod 2,如果为1,则ans++;//即查看每位上是否为2
最后ans->0
循环以上步骤计算出所有数
有n个数
每个数i计算logi次
n
∑logi
i=1
复杂度:O(nlogn)
后来在大佬的指点下,发现了可以用递推
计算count[a]的时候只要count[a>>1]计算出来了,那么如果a二进制下的末位为1,结果加1,否则不变
a>>1是位运算,就是把a在二进制下直接向右移,那么它的最后一位就没了。
example
101001111我们要计算它的1的个数,只要把10100111的1的个数加一就好了
101001110我们要计算它的1的个数,它是等于10100111的
那么我们的程序就出来了
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int count[1<<16];
for(int i=1;i<=(1<<16);i++)
{
if((i&1)==0)
count[i]=count[i>>1];
else
count[i]=count[(i>>1)]+1;
//cout<<i<<" "<<count[i]<<endl;
//system("pause");
}
}
这里有一个&运算,可能有人不懂
&就是把两个数在二进制下,每一位进行与运算,a&1就可以知道a的最后一位是什么