1. 数据小, 充分挖潜数据的特点
2. 该DP的DP, 该枚举的枚举
3. 注意将一些枚举简化成O(1)的式子:
a[i] + a[i + 1] + ... + a[j] = sum[j] - sum[i - 1]
import java.util.*;
import java.util.regex.*;
import java.text.*;
import java.math.*;
import java.awt.geom.*;
public class VerySmoothDecompositions
{
public BigInteger [] BI = new BigInteger[16];
public int [] cnt = new int[16];
public int mod = 1000000009;
public void cal_BI() {
for (int i = 0; i < 16; ++i) {
BI[i] = BigInteger.valueOf(i);
cnt[i] = 0;
}
}
public int solve(String[] dig)
{
cal_BI();
String num = "";
for (int i = 0 ; i < dig.length; ++i) {
num += dig[i];
}
BigInteger n = BI[0];
for (int i = 0 ; i < num.length(); ++i) {
n = n.multiply(BI[10]);
int k = num.charAt(i) - '0';
n = n.add(BI[k]);
}
for (int i = 2; i < 16; ++i) {
while (n.mod(BI[i]).equals(BI[0])) {
cnt[i]++;
n = n.divide(BI[i]);
}
}
if (!n.equals(BI[1])) return 0;
int [][] d = new int [cnt[2] + 1][cnt[3] + 1];
//2, 4, 8, 16, 3, 9, 6, 12
int [] dx = {1, 2, 3, 4, 0, 0, 1, 2};
int [] dy = {0, 0, 0, 0, 1, 2, 1, 1};
d[0][0] = 1;
for (int i = 0; i < dx.length; ++i) {
for (int j = dx[i]; j <= cnt[2]; ++j) {
for (int k = dy[i]; k <= cnt[3]; ++k) {
d[j][k] += d[j - dx[i]][k - dy[i]];
if (d[j][k] >= mod) d[j][k] -= mod;
}
}
}
for (int i = 0; i <= cnt[2]; ++i) {
for (int j = 1; j <= cnt[3]; ++j) {
d[i][j] += d[i][j - 1];
if (d[i][j] >= mod) d[i][j] -= mod;
}
}
int ans = 0;
for (int i = 0; i <= cnt[7]; ++i) {
for (int j = 0; j <= cnt[5]; ++j) {
int c2 = cnt[2] - i - j;
if (c2 < 0) break;
int c5 = cnt[5] - j;
// 3
int ok0 = cnt[3] - c5, ok1 = cnt[3];
if (ok0 < 0) ok0 = 0;
ans += d[c2][ok1];
if (ans >= mod) ans -= mod;
if (ok0 > 0) ans -= d[c2][ok0 - 1];
if (ans < 0) ans += mod;
}
}
return ans;
}
}