设 x x x在十进制数下有 k k k位,且 d ( x , i ) d(x,i) d(x,i)表示 x x x的第 i i i位
定义 f ( x ) = ∑ i = 1 k − 1 ∑ j = i + 1 k d ( x , i ) ∗ d ( x , j ) f(x)=\sum\limits_{i=1}^{k-1}\sum\limits_{j=i+1}^kd(x,i)*d(x,j) f(x)=i=1∑k−1j=i+1∑kd(x,i)∗d(x,j)
求在 [ L , R ] [L,R] [L,R]内满足 x = = f ( x ) % m x==f(x)\%m x==f(x)%m的个数
考虑数位 d p dp dp从高到低枚举每一个位置
定义 f [ i ] [ j ] [ q ] [ w ] f[i][j][q][w] f[i][j][q][w]为枚举到第 i i i位,前缀大小为 j j j,当前贡献为 q q q,当前数字为 w w w的方案数
考虑前 i − 1 i-1 i−1位前缀为 s u m sum sum,贡献为 r e s res res,数字为 l a s t last last
那么第 i i i位为 x x x,当前位权值为 l i li li
前缀为 ( s u m + x ) % m (sum+x)\%m (sum+x)%m,贡献变为 ( r e s + x ∗ s u m ) % m (res+x*sum)\%m (res+x∗sum)%m,当前数字变为 ( l a s t + x ∗ l i ) % m (last+x*li)\%m (last+x∗li)%m
这样时间空间复杂度都是 O ( n m 3 ) = 300000 ∗ 3600 O(nm^3)=300000*3600 O(nm3)=300000∗3600
但是可以直接维护 f ( x ) − x f(x)-x f(x)−x的值,因为我们只需要判断相等就好了
那么定义 f [ i ] [ j ] [ q ] f[i][j][q] f[i][j][q]为枚举到第 i i i位,前缀为 j j j, f ( x ) − x f(x)-x f(x)−x为 q q q的方案
设下一位填 x x x
那么前缀变为 x + j x+j x+j, f ( x ) − x f(x)-x f(x)−x变为 q + x ∗ j − x ∗ 1 0 i q+x*j-x*10^i q+x∗j−x∗10i
这题卡常太难受了…
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int n,m,bit[5009],dig[5009],f[5009][61][61][2],id,ok[5009][61][61][2];
char a[5009],b[5009];
int dfs(int num,int pre,int fx,int limit)
{
long long ans = 0;
if( num==0 ) return fx==0;
if( ok[num][pre][fx][limit]==id ) return f[num][pre][fx][limit];
ok[num][pre][fx][limit] = id;
int lim = limit?dig[num]:9;
for(int i=0;i<=lim;i++)
{
int he = ((fx+i*pre-i*bit[num])%m+m)%m;
ans = ans+dfs(num-1,(pre+i)%m,he,limit&&(i==dig[num]) );
}
ans = ( ans+mod )%mod;
f[num][pre][fx][limit] = ans;
return ans;
}
int solve( char a[] )
{
++id;
int n = strlen( a+1 );
for(int i=1;i<=n;i++) dig[i] = a[n-i+1]-'0';
return dfs(n,0,0,1);
}
int main()
{
int t; cin >> t;
while( t-- )
{
scanf("%s%s%d",a+1,b+1,&m);
int n = strlen( a+1 ),n2 = strlen( b+1 );
a[n]--;
for(int i=n;i>=1;i--)
{
if( a[i]>='0'&&a[i]<='9' ) break;
a[i] = '9', a[i-1]--;
}
bit[1] = 1;
for(int i=2;i<=n2;i++) bit[i] = bit[i-1]*10%m;
cout << ( solve(b) - solve(a) + mod )%mod << endl;
}
}