论数位DP的模板

部分代码适用,有些还是需要改的

#include <bits/stdc++.h>
using namespace std;
#define ll long long

const int N = 25;                 // 位数上限, 10^18 是 19 位

ll dp[N][/*状态维...*/];          // 不含 f, 通常不含 lead
int a[N], len;

ll dfs(int pos, /*状态...,*/ bool lead, bool f) {
    if (/*非法状态*/) return 0;              // 入口剪枝
    if (pos == 0) return /*合法判定*/;        // 语义要对
    if (!lead && !f && dp[pos][/*状态*/] != -1)  // 只在完全自由时读
        return dp[pos][/*状态*/];
    int up = f ? a[pos] : 9;
    ll ans = 0;
    for (int i = 0; i <= up; i++) {
        bool nlead = lead && (i == 0);
        // 转移: 更新状态, nlead 判前导零, f && (i==up) 传贴界
        ans += dfs(pos - 1, /*新状态,*/ nlead, f && (i == up));
    }
    if (!lead && !f) dp[pos][/*状态*/] = ans;    // 只在完全自由时写
    return ans;
}

ll solve(ll x) {
    if (x <= 0) return 0;                        // l-1 下溢兜底
    len = 0;
    while (x) { a[++len] = x % 10; x /= 10; }
    // 定长题在此加: if (len < K) return 0;
    return dfs(len, /*初始状态,*/ true, true);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    memset(dp, -1, sizeof dp);                   // 全局清一次, 跨询问复用

    int T; cin >> T;
    while (T--) {
        ll l, r; cin >> l >> r;
        cout << solve(r) - solve(l - 1) << '\n';
    }
    return 0;
}
posted @ 2026-07-05 20:10  头像是美食  阅读(9)  评论(0)    收藏  举报