题目链接:点击这里
题目大意:
给你
4
4
4 个数
m
,
d
,
l
,
r
m,d,l,r
m,d,l,r ,保证
l
,
r
l,r
l,r 位数相同。
问满足以下条件的数
x
x
x 的个数:
- l ≤ x ≤ r l \leq x\leq r l≤x≤r
- x x x 的偶数位是 d d d,奇数位不是 d d d。 (这里定义偶数位为从高位往低位的数的偶数位)
- m ∣ x m|x m∣x
答案对 1 e 9 + 7 1e9+7 1e9+7 取模
题目分析:
数位
d
p
dp
dp ,因为这里的
l
,
r
l,r
l,r 位数有点多,所以直接求
[
1
,
l
−
1
]
[1,l-1]
[1,l−1] 部分的答案比较麻烦,题目所求可以转化为先求
[
1
,
r
]
[1,r]
[1,r] 部分的答案减去
[
1
,
l
]
[1,l]
[1,l] 的答案再单独验证一下
l
l
l 这个点是否满足题意
设状态
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 为 到数位
i
i
i 对
m
m
m 取余为
j
j
j 的符合要求的数的个数
在判断当前数是否满足条件
3
3
3 时,可以用类似快读的思想把他一位一位的还原成原来的数边还原边对
m
m
m 取余,最后看取余结果是否为
0
0
0 即可
具体细节见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
ll read()
{
ll res = 0,flag = 1;
char ch = getchar();
while(ch<'0' || ch>'9')
{
if(ch == '-') flag = -1;
ch = getchar();
}
while(ch>='0' && ch<='9')
{
res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
ch = getchar();
}
return res*flag;
}
const int maxn = 2e3+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
ll m,d,a[maxn],dp[maxn][maxn];
char l[maxn],r[maxn];
ll dfs(int pos,ll state,bool limit,int len)
{
if(pos == -1) return state == 0;
if(!limit && dp[pos][state]!=-1)
return dp[pos][state];
int up = limit ? a[pos] : 9,res = 0;
for(int i = 0;i <= up;i++)
{
if((len-pos)&1)//奇数位
{
if(i == d) continue;
}
else if(i != d) continue;
res = (res+dfs(pos-1,(state*10+i)%m,limit&&(i==up),len))%mod;
}
if(!limit) dp[pos][state] = res;
return res;
}
ll solve(char s[])
{
int len = strlen(s);
for(int i = 0;i < len;i++)
a[len-i-1] = s[i]-'0';
return dfs(len-1,0,true,len);
}
bool check(char s[])
{
ll sum = 0,len = strlen(s);
for(int i = 0;i < len;i++)
{
int now = s[i]-'0';
if((i+1)&1)
{
if(now == d) return false;
}
else {
if(now != d) return false;
}
sum = (sum*10+now)%m;
}
return sum==0;
}
int main()
{
m = read(),d = read();
scanf("%s%s",l,r);
memset(dp,-1,sizeof(dp));
ll ans = ((solve(r)-solve(l)+check(l))%mod+mod)%mod;
printf("%lld\n",ans);
return 0;
}