In a palindrome, The digits with place value 10^{i-1} and 10^{n-i} are the same for 0\leq i \leq \lfloor n/2\rfloor. That’s the main observation needed.
Let dp[i][j].first Be the sum of all palindromes, whose First and last i digits are filled, and are j\ mod\ k, and dp[i][j].second be the number of such palindromes.
Now for the dp relation, find the increase if I put the next digit as l, both mod\ k and mod\ p. They are l*(10^{i-1}+10^{n-i}), mod\ k and mod\ p respectively.
Let’s call them valmodk and valmodp.
dp[i][j+valmodk].first=dp[i-1][j].first+dp[i-1][j].second*valmodp
(Obviously j+valmodk \mod k)
The first term is the sum from before, and the second term is the value created when we add a digit l
dp[i][j+valmodk].second=dp[i-1][j].second;
This one is much simpler. the number of ways didn’t increase because we set a digit. It will be overall higher because we’ll set all possible digits 1-10.
Now if it is odd, we need to then iterate over all possibilities for the standalone digit at the end.
It’s a bit difficult, especially to explain it concisely, But you can understand if you try working out the reasoning yourself. Maybe My code will make it clearer?
My code
#include <iostream>
#include <bits/stdc++.h>
#include <cmath>
#include <vector>
#define ll long long int
#define mp make_pair
#define pb push_back
#define vi vector<int>
using namespace std;
const ll p =1e9 + 7;
ll modpower(ll base, ll power, ll mod=p){
ll ans =1;
base%=mod;
while(power){
if(power&1){
ans*=base;
ans%=mod;
}
base*=base;
base%=mod;
power>>=1;
}
return ans;
}
void solve(){
int n,k;
cin>>n>>k;
vector<vector<pair<ll,ll>>> dp((n/2) + 1, vector<pair<ll,ll>>(k, mp(0,0)));
dp[0][0].second=1;
for(int i=1;i<=(n/2);i++){
for(int j=0;j<k;j++){
for(int l=0;l<10;l++){
if(i==1 && l==0){
continue;
}
ll valmodp=modpower(10, i-1)+modpower(10, n-i);
valmodp*=l;
valmodp%=p;
ll valmodk=modpower(10, i-1, k)+modpower(10, n-i, k);
valmodk*=l;
valmodk%=k;
valmodk+=j;
valmodk%=k;
dp[i][valmodk].first+=dp[i-1][j].first;
dp[i][valmodk].first+=(dp[i-1][j].second*valmodp)%p;
dp[i][valmodk].first%=p;
dp[i][valmodk].second+=dp[i-1][j].second;
dp[i][valmodk].second%=p;
}
}
}
ll ans=0;
if(n&1){
for(int l=0;l<10;l++){
ll valmodp=modpower(10, n/2)*l;
valmodp%=p;
ll valmodk=modpower(10, n/2, k)*l;
valmodk%=k;
valmodk=k-valmodk;
valmodk%=k;
ans+=dp[n/2][valmodk].first;
ans+=dp[n/2][valmodk].second*valmodp;
ans%=p;
}
}
else{
ans=dp[n/2][0].first;
}
cout<<ans<<'\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
solve();
}
Actually this will most likely TLE and you need to compute the powers 10 mod p and mod k before hand, but I don’t have the willpower to actually do it.