https://codeforces.com/gym/102452/problem/J
My teammate gave me a "isn’t this basic operation?" f(x)=(\sum{d(x,i)} ^2-\sum{(d(x,i))^2}) /2, so the things to be maintained are converted to only related to the current coordinates, and then since a sum square and each number need to be calculated separately, and there is a /2 behind, then m=2m, and then 120 space I can’t open it, and the time is not good enough. I fall into a long autism.
Then I found that as long as the prefix sum and the remaining two dimensions are maintained, without this /2, the space of 60 can be stuck, and the time has been optimized by 4 times, and it is much simpler
dp[k][x][y] is the case where the prefix sum to the k-th position is x, y is the difference between x and f(x) before i is %m
Then suppose the number i is currently selected, then the transfer is dp[k][x][y]->dp[i][x+i][y+x*ii*mi[len-i]], because the new entry 1 Bit f(x) adds prefix and *i
In the end, there is only one solution when y==0
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxl=5e3+10;
const int mod=1e9+7;
int llen,rlen,m,len,mt;
ll ans;
int a[maxl];
ll dp[maxl][61][61][2];
int clk[maxl][61][61][2];
int mi[maxl];
char l[maxl],r[maxl];
inline void prework()
{
scanf("%s",l+1);
llen=strlen(l+1);
scanf("%s",r+1);
rlen=strlen(r+1);
scanf("%d",&m);
}
inline void add(ll &x,ll y)
{
x=(x+y)%mod;
}
inline int mo(int x)
{
return (x%m+m)%m;
}
inline ll dfs(int k,int x,int y,bool f)
{
if(k>len)
return y==0;
if(clk[k][x][y][f]==mt)
return dp[k][x][y][f];
int up=f?a[k]:9;
dp[k][x][y][f]=0;
for(int i=0;i<=up;i++)
add(dp[k][x][y][f],dfs(k+1,(x+i)%m,mo(y+x*i-mi[len-k]*i),f && (i==up)));
clk[k][x][y][f]=mt;
return dp[k][x][y][f];
}
inline void mainwork()
{
len=rlen;mi[0]=1;++mt;
for(int i=1;i<=len;i++)
a[i]=r[i]-'0',mi[i]=mi[i-1]*10%m;
ll tmp1=dfs(1,0,0,1);
len=llen;++mt;
for(int i=1;i<=len;i++)
a[i]=l[i]-'0';
ll tmp2=dfs(1,0,0,1);
int x=0;
for(int i=1;i<=llen;i++)
x=(x+mi[llen-i]*a[i])%m;
int fx=0;
for(int i=1;i<llen;i++)
for(int j=i+1;j<=llen;j++)
fx=(fx+a[i]*a[j])%m;
if(fx==x)
ans=((tmp1-tmp2+1)%mod+mod)%mod;
else
ans=((tmp1-tmp2)%mod+mod)%mod;
}
inline void print()
{
printf("%lld\n",ans);
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}