Solution
将数字看成二进制
f[i][j]表示前i为中有j个1的数的总数
f[i][j]=f[i−1][j−1]+f[i−1][j]
然后逐位统计即可
Code
// by spli
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
const LL p=10000007;
LL n;
LL f[70][70];
int bit[70],num=0;
LL exp(LL a,LL b){
LL ret=1,k=a%p;
while(b){
if(b&1) (ret*=k)%=p;
b>>=1;
(k*=k)%=p;
}
return ret%p;
}
LL get(int x){
LL s=0;
for(int i=num;i>=1;--i){
if(bit[i]==1){
s+=f[i-1][x];
x--;
}
if(x<0) break;
}
return s;
}
int main(){
scanf("%lld",&n);
n++;
for(int i=0;i<=60;++i) f[i][0]=1;
for(int i=1;i<=60;++i)
for(int j=1;j<=i;++j)
f[i][j]=f[i-1][j]+f[i-1][j-1];//取模会WA
while(n){
bit[++num]=n&1;
n>>=1;
}
LL ans=1;
for(int i=1;i<=num;++i)
(ans*=exp((LL)i,get(i)))%=p;
printf("%lld\n",ans);
return 0;
}