背景
众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。
描述
话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
花神的题目是这样的
设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你
派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。
标签:补充 print 二进制 背景 for work tput input 解释权
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
背景
众所周知,花神多年来凭借无边的神力狂虐各大 OJ、OI、CF、TC …… 当然也包括 CH 啦。
描述
话说花神这天又来讲课了。课后照例有超级难的神题啦…… 我等蒟蒻又遭殃了。
花神的题目是这样的
设 sum(i) 表示 i 的二进制表示中 1 的个数。给出一个正整数 N ,花神要问你
派(Sum(i)),也就是 sum(1)—sum(N) 的乘积。
一个正整数 N。
一个数,答案模 10000007 的值。
对于样例一,1*1*2=2;
数据范围与约定
对于 100% 的数据,N≤10^15
//It is made by ljh2000 #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; typedef long long LL; const LL MOD = 10000007; LL n,C[120][120],ans; int cnt,k,a[120]; inline LL fast_pow(LL x,LL y){ LL r=1; while(y>0) { if(y&1) r*=x,r%=MOD; x*=x; x%=MOD; y>>=1; } return r; } inline void work(){ scanf("%lld",&n); while(n>0) { a[++cnt]=n&1; n>>=1; } C[0][0]=1; k=0; ans=1; for(int i=1;i<=60;i++) { C[i][0]=1; for(int j=1;j<=i;j++) C[i][j]=C[i-1][j]+C[i-1][j-1]/*指数不能直接取模*/; } for(int i=cnt;i>=1;i--) { if(a[i]) { ans*=(k+1); ans%=MOD; for(int j=1;j<i;j++) ans*=fast_pow(k+j,C[i-1][j]),ans%=MOD; //枚举i-1位到最低位中的1的个数j,则总共1的个数位j+k,同时出现次数就为C[i-1][j] k++;//多了一个1 } } printf("%lld",ans); } int main() { work(); return 0; }
标签:补充 print 二进制 背景 for work tput input 解释权
原文地址:http://www.cnblogs.com/ljh2000-jump/p/6235016.html