数位DP
#define D 10
#define L 21
int a[L];
LL dp[L][D][]...;
LL dfs(int len, int pos, int pre, int st, ..., int lead, int limit) {
if (pos > len) {
return st;
}
if (!lead && !limit && dp[pos][pre][st]...) {
return dp[pos][pre][st]...;
}
LL ret = 0;
int res = limit ? a[len - pos + 1] : D - 1;
for (int i = 0; i <= res; ++i) {
if (lead && !i) { //有前导0并且当前位也是前导0
ret += dfs(len, pos + 1, 0, ..., 1, limit && i == res);
} else if (lead && i) { //有前导0但当前位不是前导0,当前位就是最高位
ret += dfs(len, pos + 1, i, ..., 0, limit && i == res);
} else if (...) { //其他情况
ret += dfs(len, pos + 1, i, ..., 0, limit && i == res);
}
}
if (!lead && !limit) {
dp[pos][pre][st]... = ret;
}
return ret;
}
LL part(LL x) {
int len = 0;
for (; x; x /= 10) {
a[++len] = x % 10;
}
memset(dp, -1, sizeof dp);
return dfs(len, 1, ..., 0, ..., 1, 1);
}
LL solve(LL l, LL r) {
if (l) {
return part(r) - part(l - 1);
} else {
return part(r) - part(l);
}
}
Comments NOTHING