来自:http://blog.csdn.net/xaphoenix/article/details/50709584
设sum(i)为i在二进制下的1的个数,求sum(1)~sum(n)的乘积模1e8+7的值。n< =1e15
将n加1后,转为二进制,然后数位dp:先找到包含k个1的数字有多少个 那么答案就是k^f(k)的乘积,所以先用数位dp预处理下i位j个1的有多少个即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<cmath>
typedef long long LL;
using namespace std;
LL N,M,T;
LL X[65][65];
LL a[61];
LL len;
const LL mod = 10000007;
LL quick_mod(LL a,LL i)
{
if (i==0) return 1%mod;
LL temp=quick_mod(a,i>>1);
temp=temp*temp%mod;
if (i&1) temp=(LL) temp*a%mod;
return temp;
}
LL solve(LL x)
{
LL res=0;
for (int i=len;i>=1;i--)
{
if (a[i])
{
res+=X[i-1][x];
x--;
}
if (x<0) return res;
}
return res;
}
int main()
{
for(LL i=0;i<60;i++)
{
X[i][0]=1;
for(LL j=1;j<=i;j++)
{
X[i][j]=X[i-1][j]+X[i-1][j-1];
}
}
cin>>N;
N++;
len=0;
while(N)
{
a[++len]=N%2;
N>>=1;
}
LL ans=1;
for(int i=1;i<=len;i++)
{
ans=ans*quick_mod(i,solve(i))%mod;
}
cout<<ans<<endl;
return 0;
}