一道数位DP题,仔细看题分析一下就知道是求什么。
数位DP的新套路,可以将lim也记录进答案保证复杂度
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9 + 7;
const int N = 222;
const int CMAX = 1e5 + 5;
int t , m , n , dp[222][2][2] , A[N] , B[N] , k , ln , lm;
int T[100005];
int Div(int x , int k) {
int now = 0;
while(x % k == 0) x /= k , ++ now;
return now;
}
void init(void) {
T[0] = 0;
for(int i = 1;i < 100005;++ i) {
T[i] = T[i - 1] + Div(i , k);
}
}
int convert(int x , int *A) {
int len = 0;
while(x) {
A[++ len] = x % k;
x /= k;
}
return len;
}
int dfs(int pos , int l1 , int l2) {
if(!pos) return 1;
if(dp[pos][l1][l2] != -1) return dp[pos][l1][l2];
int res = 0 , up = (l1) ? A[pos] : (k - 1);
for(int i = 0;i <= up;++ i) {
if(!l2 || (l2 && B[pos] > i)) {
res = (res + (i + 1) % mod * dfs(pos - 1 , (l1 && (i == up)) , 0) % mod) % mod;
continue;
}
int up2 = B[pos];
res = (res + (B[pos]) * dfs(pos - 1 , (l1 && (i == up)) , 0) % mod) % mod;
res = (res + dfs(pos - 1 , (l1 && (i == up)) , 1) % mod) % mod;
}
dp[pos][l1][l2] = res;
return res;
}
int baoli(int n , int m) {
int ans = 0;
for(int i = 0;i <= n;++ i) {
for(int j = 0;j <= min(i , m);++ j) {
if(T[i] - T[j] - T[i - j] == 0) continue;
++ ans;
}
}
return ans % mod;
}
const int inv2 = mod / 2 + 1;
void dance(void) {
scanf("%lld%lld" , &n , &m);
memset(A , 0 , sizeof(A)); memset(B , 0 , sizeof(B));
memset(dp , -1 , sizeof(dp));
ln = convert(n , A); lm = convert(m , B);
// cerr << ln << endl;
long long ans = dfs(ln , 1 , (m < n));
long long res = 0;
if(n <= m) n %= mod , res = (n + 2) % mod * ((n + 1) % mod) % mod * inv2 % mod;
else {
n %= mod , m %= mod;
res = (m + 2) % mod * (m + 1) % mod * inv2 % mod + (n - m + mod) % mod * (m + 1) % mod;
res %= mod;
}
cout << (res - ans + mod) % mod << endl;
}
main(void) {
scanf("%lld%lld" , &t , &k);
while(t --) {
dance();
}
}