Topic links: point I ah ╭ (╯ ^ ╰) ╮
Subject to the effect:
Length of
number, the location is part
,
It can be
~
requires this number is divisible by
,
times ask
Always ask first
small solutions
Problem-solving ideas:
for
Be split in
Then consider
The program,
question mark number of programs
as
, if
number in the uniform distribution, divisible
number of about
therefore
can be, that is, after explore
question mark scheme foregoing question mark taken as
is the first to
question mark, die
is
program numbers
Note
time, you want to add to the initial impact, that is,
can be understood as the first to solve the initial impact, if not the most greedy with high
time to enumerate the query from high to low, the initial impact while also taking into account the first
time the complexity:
Core: DP + thinking
#include<bits/stdc++.h>
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
const int maxn = 5e4 + 5;
const ll mod = 1e9 + 7;
int T, n, m, q;
char s[maxn];
ll dp[30][30], fac1[50], fac2[50];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d%d%d%s", &n, &m, &q, s);
ll p1 = 1, p2 = 1, val = 0, rem = 0, cnt = 0, k;
for(int i=n-1; ~i; i--) {
if(isdigit(s[i])) {
val = (val + (s[i]-'0') * p1 % mod) % mod;
rem = (rem + (s[i]-'0') * p2 % m) % m;
} else if(cnt < 20) {
fac1[++cnt] = p1;
fac2[cnt] = p2;
}
p1 = p1 * 10 % mod;
p2 = p2 * 10 % m;
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for(int i=1; i<=cnt; i++)
for(int j=0; j<m; j++)
for(int x=0; x<10; x++) {
if(i > 1) dp[i][j] += dp[i-1][(j + fac2[i] * x % m) % m];
else dp[i][j] += dp[i-1][(j + rem + fac2[i] * x % m) % m];
if(dp[i][j] >= 1e18 + 10 || dp[i][j] < 0) dp[i][j] = 1e18 + 10;
}
while(q--) {
scanf("%lld", &k);
if(dp[cnt][0] < k) {
puts("-1");
continue;
}
ll ans = val, pre_rem = 0, now_rem;
for(int i=cnt; i; i--)
for(int x=0; x<10; x++) {
if(i > 1) now_rem = (pre_rem + fac2[i] * x % m) % m;
else now_rem = (pre_rem + rem + fac2[i] * x % m) % m;
if(dp[i-1][now_rem] < k) k -= dp[i-1][now_rem];
else {
pre_rem = now_rem;
ans = (ans + fac1[i] * x % mod) % mod;
break;
}
}
printf("%lld\n", ans);
}
}
}