题解:可以发现出现次数非常少(最多不超过60)可以每次找出出现 i 次数对应的(l~r)中的数n多少个那么单对于这个次数贡献值就是n*(i^k) 找每个i对用的n要用数位dp
dp[dep][nd][zero][lim] 表示已经遍历到第i位,d还需要出现j次(之前已经出现i-nd次)然后此位是否维护前导零,是否有最高位限制,还有一些讨论细节
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define fi first
#define se second
#define pb push_back
#define lowbit(x) ((x)&(-x))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define all(x) x.begin(),x.end()
#define SZ(x) ((int)(x).size())
#define debug(var) cout<< #var << " = " << var << endl
using namespace std;
std::mt19937_64 rng;
const int N = 6e5 + 10, mod = 1e9 + 7;
typedef pair<int, int>PII;
int m, n;
//
int dp[100][100][2][2], s[100], k, B, d;
int qpow(int x, int n)
{
int ans = 1;
while(n)
{
if(n % 2) ans = ans * x % mod;
x = x * x % mod;
n /= 2;
}
return ans;
}
int dfs(int dep, int nd, int zero, int lim)
{
if(dep == m + 1)
{
if(nd == 0) return 1;
else return 0;
}
if(nd < 0) return 0;
if(dp[dep][nd][zero][lim] != -1) return dp[dep][nd][zero][lim];
else dp[dep][nd][zero][lim] = 0;
int up = lim ? s[dep] : (B - 1);
int other = up + 1;
// 讨论细节:主要分 这位是 d ,up other,维护前导0的0 因为这几类传的参数不一样;
// 其中还要注意有可能这一类的情况上一类加过了
if(d == 0)
{
dp[dep][nd][zero][lim] += dfs(dep + 1, nd - (zero == 0), zero, lim && up == 0);
other--;
}
else if(d <= up)
{
dp[dep][nd][zero][lim] += dfs(dep + 1, nd - 1, 0, lim && s[dep] == d);
other--;
}//d
if( d != up) dp[dep][nd][zero][lim] += dfs(dep + 1, nd, zero && !up, lim), other--;// up
if(d && up) dp[dep][nd][zero][lim] += dfs(dep + 1, nd, zero, 0), other--; //zero
dp[dep][nd][zero][lim] += dfs(dep + 1, nd, 0, 0) * other % mod;
dp[dep][nd][zero][lim] %= mod;
return dp[dep][nd][zero][lim] ;
}
int sum(int x)
{
m = 0;
while(x)
{
s[++m] = x % B;
x /= B;
}
rep(i, 0, m) rep(j, 0, m) rep(k, 0, 1) rep(z, 0, 1) dp[i][j][k][z] = -1;
reverse(s + 1, s + 1 + m);
int ans = 0;
rep(i, 1, m)
{
ans += dfs(1, i, 1, 1) * qpow(i, k) % mod;
ans %= mod;
}
return ans;
}
void solve()
{
int l, r;
cin >> k >> B >> d >> l >> r;
int ans = sum(r) - sum(l - 1) + mod;
cout << ans % mod << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << fixed << setprecision(12);
int T = 1;
cin >> T;
while(T--)solve();
// fclose(stdin);
// fclose(stdout);
return 0;
}