我写的数论dp,dfs形式,小调试一下感觉问题应该出在限制的锅?(3、7等二进制全为1的数跟题解对拍能过,其他过不了)
//#include <bits/stdc++.h>
#include <queue>
#include <iostream>
#include <iomanip>
#include <math.h>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#define F(i, a, b) for(register int i = a, i##end = b; i <= i##end; i++)
#define UF(i, a, b) for(register int i = a, i##end = b; i >= i##end; i--)
#define ll long long
using namespace std;
inline ll read()
{
ll x = 0;
bool fu = 0;
char ch = 0;
while(ch > '9' || ch < '0')
{
ch = getchar();
if(ch == '-')
fu = 1;
}
while(ch <= '9' && ch >= '0')
x = (x * 10 - 48 + ch), ch = getchar();
return fu ? -x : x;
}
const ll mod = 10000007;
ll dp[70][70];
ll n;
int pos;
int limits[70];
ll dfs(int n, int m, int limit)
{
if(n < m || m < 0)//不合法
{
return 0;
}
if(n == 0)//合法的基本单位
{
return 1;
}
if(dp[n][m])//记忆化搜索
{
return dp[n][m];
}
if(!limit)//不被限制
{
return dp[n][m] = dfs(n - 1, m, 0) + dfs(n - 1, m - 1, 0);//0或1都不被限制
}
if(limits[n])//被限制,但是此位有两种选择
return dp[n][m] = dfs(n - 1, m, 0) + dfs(n - 1, m - 1, 1);//选0则下一位不被限制,选1则下一位仍被限制
return dp[n][m] = dfs(n - 1, m, 1);//只能选0,下一位必被限制
}
ll qpow(ll a, ll b)
{
ll ans = 1;
while(b)
{
if(b & 1)
{
ans *= a;
ans %= mod;
}
a *= a;
a %= mod;
b >>= 1;
}
return ans;
}
int main()
{
ll ans = 1;
n = read();
while(n)
{
limits[++pos] = n & 1;
n >>= 1;
}
F(i, 1, pos)
{
dfs(pos, i, 1);
}
F(i, 1, pos)
{
ans = ans * qpow(i, dp[pos][i]) % mod;
}
printf("%lld\n", ans);
getchar();
return 0;
}