Description
给定 (d),如果一个数从高往低数第奇数位都是 (d),第偶数位都不是 (d),那么这个数称为 d-magic 数。
给定两个长度相等的数 (l,r)。求 ([l,r]) 中有多少个 d-magic 数,答案 (mod 10^9+7)。(l,r) 的长度 (n le 2000)。
Solution
转化为 (f(r)-f(l-1)) 的话还要做一下高精度减法,比较麻烦,所以我们就直接处理了。
对于每个状态,维护 (pos) 表示当前扫到从左到右的第 (pos) 位,(rem) 表示前 (i) 个数位构成的数的余数是 (rem),用两个标记 (tagl,tagr) 表示左边界和右边界是否已经与当前数分离。
转移过程显然是去枚举当前数位的所有可能取值,然后递归做下去。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2005;
const int mod = 1e9 + 7;
string a,b;
int m,d,f[N][N][2][2];
int solve(int pos,int rem,int tagl,int tagr)
{
if(pos==a.length())
{
return !rem;
}
else
{
if(~f[pos][rem][tagl][tagr])
{
return f[pos][rem][tagl][tagr];
}
else
{
int ans=0;
for(int now=0;now<=9;now++)
{
char c=now+'0';
if((tagl || c>=a[pos]) && (tagr || c<=b[pos]) && (pos%2==(now==d)))
{
ans+=solve(pos+1,(rem*10+now)%m,tagl||c>a[pos], tagr||c<b[pos]);
ans%=mod;
}
}
return f[pos][rem][tagl][tagr]=ans;
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin>>m>>d>>a>>b;
memset(f,-1,sizeof f);
cout<<solve(0,0,0,0);
}