【题面链接】
首先我们知道11,13这两个因子对分解数无影响
对于这道题,我们可以从
另有 10%的数据,D 只含有 2 个素因子。
这个数据点思考
如果这两个质因子是2,3那么我们可以很轻易地写出DP方程
- 设f[c][i][j]表示只使用前c个只由2,3组成的数并有i个2,j个3供使用–的分解方案数(代码实现上可省略第一维)
- w[c][0],w[c][1]分别表示前c个只由2,3组成的数使用的2,3个数
f[i][j] = f[i][j]+f[i-w[c][0]][j-w[c][1]];
如果还有因子5,7那么如果我们继续增加维数则会TLE or MLE
那么我们怎么办呢?
考虑到5只能与2,3组合,7只能与2组合,那么我们可以先算出只用因子2,3的方案数,最后用组合数学统计答案。
- code
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 8005, mod = (int)1e9 + 9;
long long f[maxn][maxn];
int n, s[2505], d[2505], a[6];
void factor()
{
int p[6] = {2, 3, 5, 7, 11, 13};
memcpy(s, d, sizeof(s));
for(int i = 0; i < 4; ++i) {
memcpy(d, s, sizeof(d));
do {
a[i]++;
for(int j = 1; j <= n; ++j) {
d[j + 1] += (d[j] % p[i]) * 10;
d[j] /= p[i];
}
}while(!d[n + 1]);
a[i]--;
}
}
const int w[8][2] = {
1, 0, 0, 1, 2, 0, 1, 1, 3, 0, 0, 2, 2, 1, 4, 0
};
int main()
{
freopen("factor.in", "r", stdin);
freopen("factor.out", "w", stdout);
char c;
do {
c = getchar();
}while(c < '0' || c > '9');
do {
d[++n] = c - 48;
c = getchar();
}while('0' <= c && c <= '9');
factor();
f[0][0] = 1;
for(int c = 0; c < 8; ++c) {
for(int i = 0; i <= a[0]; ++i)
for(int j = 0; j <= a[1]; ++j)
if(i >= w[c][0] && j >= w[c][1])
f[i][j] = (f[i][j] + f[i - w[c][0]][j - w[c][1]]) % mod;
}
long long ans = 0;int cnt = 0;
for(int i = 0; i <= a[0]; ++i)
for(int j = 0; j <= a[1]; ++j)
if(i + j <= a[2] + a[3] && j <= a[2]) {
long long w = min(a[2] - j, i) - max(0, i - a[3]) + 1ll;
(ans += w * f[a[0] - i][a[1] - j]) %= mod;
}
printf("%lld", ans);
return 0;
}
代码格式伪了,请见谅