小C的二进制难题

题目 :

小C的二进制难题

描述

小 C 研究数学日渐憔悴,他最近对二进制数中 1 的个数十分感兴趣,他定义:cnt(x) 表示 x 的二进制下 1 的个数。
他想知道 ∑ i = 0 2 n c n t ( i ) \sum_{i=0}^{2^n} cnt(i) i=02ncnt(i) 的值 ,你能帮帮他吗? 由于值可能非常大你需要对答案模上 20190414。

Input

第一行包含一个整数
T(1≤T≤1000) 代表测试组数,对于每一组测试:

第一行一个整数
n (0≤n≤ 1 0 6 10^6 106) ,n 的含义如上所述。

Output

对于每组测试,输出一行,表示答案。

Sample Input

2
2
100

Sample Output

5
13308891

思路

00000                                0

00001                                1

00010                                2
00011                                3

00100                                4
00101                                5
00110                                6
00111                                7

01000                                8
01001                                9
01010                               10
01011                               11
01100                               12
01101                               13
01110                               14
01111                               15

010000                              16

观察规律可知 ∑ i = 0 2 n c n t ( i ) \sum_{i=0}^{2^n} cnt(i) i=02ncnt(i)=n*(2^n-1)+1。
比如n=2的时候,看上图,2的二进制和3的二进制开始有1的位数的时候(从第n位也就是第二位开始有1,所以有n列),后面是0的位数,正好是1的二进制1的位数(补全后行的个数正好是2^n-1 )再加上4的二进制1的个数,2^n的二进制的1的个数都为1个,所以可以推出上述公式。

代码

#include<iostream>
using namespace std;
long long a[1000006];
const long long Mod=20190414;
long long qmi(long long a,long long b)
{
	long long ans=1;
	while(b)
	{
		if(b&1) ans=ans*a%Mod;
		b>>=1;
		a=a*a%Mod;
	}
	return ans;
}
int main()
{
	int t,n;
	cin>>t;
	a[0]=1;
	for(long long i=1;i<=1000000;i++)
	{
		a[i]=(i*qmi(2,i-1)%Mod+1)%Mod;//这里用快速幂求2^n-1
	}
	while(t--)
	{
		cin>>n;
		cout<<a[n]<<endl;
	}
	return 0;
}

注意事项

这里需要用一个数组存结果,防止重复计算,如果不用数组存的话会超时。计算的时候我也是用的快速幂计算的。

题目地址:小C的二进制难题

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值