.
.
.
传送门
显 然 , 数 位 d p + k m p , 对 于 当 前 位 失 配 后 , 跳 失 配 指 针 ( N e x t 数 组 ) 显然,数位dp+kmp,对于当前位失配后,跳失配指针(Next数组) 显然,数位dp+kmp,对于当前位失配后,跳失配指针(Next数组)
注 意 判 前 导 零 注意判前导零 注意判前导零
c o d e : code: code:
#include <set>
#include <map>
#include <list>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <bitset>
#include <vector>
#include<cstring>
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
typedef unsigned long long ull;
inline int read(){int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();return s*w;}
const int maxn = 5e3+5;
int Next[maxn];
string p;
int lp;
void Kmp_pre(int n)
{
for(int i=1,j=0;i<n;i++)
{
while (j&&p[i]!=p[j]) j=Next[j-1];
if(p[i]==p[j]) j++;
Next[i]=j;
}
}
ll dp[maxn][maxn],mod=1e9+7; // dp[pos][l] ,l:失配指针
vector<int>vec;
int Kmp(int num,int L)
{
char str=(char)(num+48);
while (L&&p[L]!=str) L=Next[L-1];
if(p[L]==str) L++;
return L;
}
ll dfs(int pos,int l,bool lead,bool limit)
{
if(pos==-1) return 1;
if(!lead&&!limit&&dp[pos][l]!=-1) return dp[pos][l];
int up=limit?vec[pos]:9;
ll ans=0;
for(int i=0;i<=up;i++)
{
int L=l;
if(lead&&i==0) ans=(ans+dfs(pos-1,L,i==0,limit&&i==vec[pos]))%mod;
else
{
L=Kmp(i,L); // 进入匹配
if(L==lp) continue;
ans=(ans+dfs(pos-1,L,lead&&i==0,limit&&i==vec[pos]))%mod;
}
}
if(!lead&&!limit) dp[pos][l]=ans;
return ans;
}
ll solve(string s)
{
vec.clear();
int len=s.size();
for(int i=len-1;i>=0;i--) vec.push_back(s[i]-48);
return dfs(len-1,0,true,true);
}
int main()
{
string l,r;
cin>>l>>r>>p;
lp=p.size();
Kmp_pre(lp);
int len=l.size();
for(int i=len-1;i>=0;i--) // l-1
{
if(l[i]=='0') l[i]='9';
else { l[i]=l[i]-1; break;}
}
string LL;
bool flag=false;
for(int i=0;i<len;i++) // 去除(l-1)后的前导零
{
if(!flag&&l[i]=='0') continue;
else LL=LL+l[i],flag=true;
}
memset(dp,-1,sizeof(dp));
ll Lr=0,lr=0;
for(int i=0;i<r.size();i++) // 字符串取模
Lr=(Lr*10%mod+r[i]-48)%mod;
for(int i=0;i<LL.size();i++)
lr=(lr*10%mod+LL[i]-48)%mod;
Lr=(Lr-lr+mod)%mod;
ll sum=(solve(r)-solve(LL)+mod)%mod;
ll ans=(Lr-sum+mod)%mod;
printf("%lld\n",ans);
return 0;
}
/*
// 特殊样例, 所以得判断前导零
302 78390 0
26258
*/