大眼萌妹刚学OI,数位dp为什么60分
查看原帖
大眼萌妹刚学OI,数位dp为什么60分
141944
海边微风起楼主2022/10/16 17:22

数据1e8的时候还能过,1e9就过不去了,已经define int long long,实在找不出问题了,求大佬帮助

#include <bits/stdc++.h>

using namespace std;

#define int long long
typedef long long ll;
const int mod = 1e7 + 7;

ll n, dp[60][60]; // i位1的个数为j的方案数 

inline ll power_mod(ll a, ll b) {
	ll ans = 1ll;
	while (b) {
		if (b & 1) ans = ans * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return ans;
}


ll a[60];

inline ll dfs(int k, int num) {
	if (k == 0) return num;
	ll ans = 1ll;
	if (a[k] == 0) return dfs(k - 1, num) % mod;
	else {
		for (int i = 0; i < k; ++i) {
			ans *= power_mod(num + i, dp[k - 1][i]);
			ans %= mod;
		}
		ans *= dfs(k - 1, num + 1);
		ans %= mod;
		return ans;
	}
}

inline ll query(ll x) {
	ll k = 0, y = x;
	while (y) {
		if (y & 1) a[++k] = 1;
		else a[++k] = 0;
		y >>= 1;
	}
	ll ans = 1ll;
	ans *= dfs(k - 1, 1ll);
	ans %= mod;
	for (int i = k - 1; i >= 1; --i) 
		for (int j = 0; j <= i - 1; ++j) {
			ans *= power_mod(j + 1, dp[i - 1][j]);
			ans %= mod;
		}
	return ans;
}

signed main() {
	for(int i = 0; i <= 55; ++i) dp[i][0] = 1ll;
	for(int i = 1; i <= 55; ++i) 
		for(int j = 1; j <= 55; ++j) 
			dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1]) % mod;
	scanf("%lld", &n);
	printf("%lld\n", query(n));
	return 0;
}

2022/10/16 17:22
加载中...