用数位dp计算有 N以内的数字 有k 个 1的数字有多少个,然后快速幂。
数位dp 直接在二进制位上进行枚举。
坑点:1e7 + 7 不是素数,但数位dp 内部无须取模数值不会爆long long
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7 + 100;
const ll mod = 1e7 + 7;
ll dp[70][70][2],N;
ll fpow(ll a,ll b) {
ll r = 1;
while(b) {
if(b & 1) r = r * a % mod;
b >>= 1;
a = a * a % mod;
}
return r;
}
ll dfs(int cur,int num,int limit) {
if(cur < 0) {
if(num == 0) return 1;
else return 0;
}
if(num < 0 || cur + 1 < num) return 0;
if(dp[cur][num][limit] != -1)
return dp[cur][num][limit];
ll &ans = dp[cur][num][limit] = 0;
int up = limit ? (N >> cur) & 1 : 1;
for(int i = 0; i <= up; i++) {
ans += dfs(cur - 1,num - i,limit && i == up);
}
return ans;
}
ll solve() {
if(N == 0) return 0;
ll res = 1,p = 0;
memset(dp,-1,sizeof dp);
for(int i = 1; i <= 62; i++) {
ll t = dfs(62,i,1);
res = res * fpow(i,t) % mod;
}
return res;
}
int main() {
scanf("%lld",&N);
printf("%lld\n",solve());
return 0;
}