P4317 花神的数论题

数位 dp。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int p = 10000007;
int bits[105], cnt;
int f[105][105][2];
int dfs(int pos, int tot1, int isl, int zero)
{
	if(pos == cnt + 1)
	{
		return tot1 - 1;
	}
	if(!isl && f[pos][tot1][isl])
	{
		return f[pos][tot1][isl];
	}
	int &ans = f[pos][tot1][isl], r = (isl ? bits[pos] : 1);
	ans = 1;
	for(int k = 0; k <= r; k++)
	{
		if(pos == cnt && zero && !k)
		{
			continue;
		}
		if(zero && !k)
		{
			ans *= dfs(pos + 1, tot1 + k, isl && (k == r), 1);
			ans %= p;
		}
		else
		{
			ans *= dfs(pos + 1, tot1 + k, isl && (k == r), 0);
			ans %= p;
		}
	}
	return ans;
}
int query(int x)
{
	cnt = 0;
	while(x)
	{
		bits[++cnt] = x & 1;
		x >>= 1;
	}
	reverse(bits + 1, bits + cnt + 1);
	memset(f, 0, sizeof(f));
	return dfs(1, 1, 1, 1);
}
signed main()
{
	int n;
	scanf("%lld", &n);
	printf("%lld", query(n));
	return 0;
}