观察数据范围,考虑数位 DP。
首先把长串中 $len\geq\lfloor \frac{d}{2}\rfloor$ 的串提出来,塞进一个 trie 里,然后建立 ACAM,然后直接 DP 就行了。
设 $f_{i,j,0/1,0/1,0/1}$ 表示当前在 trie 图上走了 j 步到达了第 i 个节点,是否已经出现子串,是否满足低位限制,是否满足高位限制,枚举 $k$ 表示第 $j$ 个字符是什么,然后在 AC 自动机上跑。第三个 $0/1$ 在走到一个结束点后就一定是 $1$,第四个维度选了一个大于 $x$ 串当前位的字符后变成 $1$,第五个维度也是同理,细节比较多,但是实在是没有任何思维含量。详细的转移方程见代码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
inline void Madd(int&x,int y){x+y>=MOD?x=x+y-MOD:x=x+y;}
int n,d,ans,f[2][500001][2][2][2];
char s[1001],t1[1001],t2[1001];
namespace ACAM
{
int end[500001],trie[500001][10],fail[500001],cnt=1;
queue<int> q;
inline void build()
{
for(int i=0;i<10;++i)trie[0][i]=1;
for(int i=1;i+d/2-1<=n;++i)
{
int now=1;
for(int j=i;j<=min(n,i+d/2-1);++j)
{
if(!trie[now][s[j]-'0'])trie[now][s[j]-'0']=++cnt;
now=trie[now][s[j]-'0'];
if(j>=i+d/2-1)end[now]=1;
}
}
q.e(1);
while(!q.empty())
{
int now=q.front();q.pop();
for(int i=0;i<10;++i)
{
if(trie[now][i])fail[trie[now][i]]=trie[fail[now]][i],q.e(trie[now][i]);
else trie[now][i]=trie[fail[now]][i];
}
}
}
}
using namespace ACAM;
#define g f[pre][trie[i][k]]
#define nw f[now][i]
inline void mian()
{
scanf("%s%s%s",s+1,t1+1,t2+1),ans=0,n=strlen(s+1),d=strlen(t1+1);
for(int i=1;i<=d;++i)t1[i]-='0',t2[i]-='0';
build(),f[1][1][0][0][0]=1;int now=0,pre=1;
for(int j=0;j<d;++j)
{
now^=1,pre^=1,memset(f[pre],0,sizeof(f[pre]));
for(int i=1;i<=cnt;++i)
{
for(int k=0;k<10;++k)
{
int is=end[trie[i][k]];
if(k<t1[j+1])
{
if(k<t2[j+1])
{
Madd(g[is|0][1][1],nw[0][1][0]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][1][1],nw[1][1][0]),Madd(g[is|1][1][1],nw[1][1][1]);
}
else if(k==t2[j+1])
{
Madd(g[is|0][1][0],nw[0][1][0]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][1][0],nw[1][1][0]),Madd(g[is|1][1][1],nw[1][1][1]);
}
else
{
Madd(g[is|0][1][1],nw[0][1][1]),Madd(g[is|1][1][1],nw[1][1][1]);
}
}
else if(k==t1[j+1])
{
if(k<t2[j+1])
{
Madd(g[is|0][0][1],nw[0][0][0]),Madd(g[is|0][0][1],nw[0][0][1]);
Madd(g[is|0][1][1],nw[0][1][0]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][0][1],nw[1][0][0]),Madd(g[is|1][0][1],nw[1][0][1]);
Madd(g[is|1][1][1],nw[1][1][0]),Madd(g[is|1][1][1],nw[1][1][1]);
}
else if(k==t2[j+1])
{
Madd(g[is|0][0][0],nw[0][0][0]),Madd(g[is|0][0][1],nw[0][0][1]);
Madd(g[is|0][1][0],nw[0][1][0]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][0][0],nw[1][0][0]),Madd(g[is|1][0][1],nw[1][0][1]);
Madd(g[is|1][1][0],nw[1][1][0]),Madd(g[is|1][1][1],nw[1][1][1]);
}
else
{
Madd(g[is|0][0][1],nw[0][0][1]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][0][1],nw[1][0][1]),Madd(g[is|1][1][1],nw[1][1][1]);
}
}
else
{
if(k<t2[j+1])
{
Madd(g[is|0][1][1],nw[0][0][0]),Madd(g[is|0][1][1],nw[0][0][1]);
Madd(g[is|0][1][1],nw[0][1][0]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][1][1],nw[1][0][0]),Madd(g[is|1][1][1],nw[1][0][1]);
Madd(g[is|1][1][1],nw[1][1][0]),Madd(g[is|1][1][1],nw[1][1][1]);
}
else if(k==t2[j+1])
{
Madd(g[is|0][1][0],nw[0][0][0]),Madd(g[is|0][1][0],nw[0][1][0]);
Madd(g[is|0][1][1],nw[0][0][1]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][1][0],nw[1][0][0]),Madd(g[is|1][1][0],nw[1][1][0]);
Madd(g[is|1][1][1],nw[1][0][1]),Madd(g[is|1][1][1],nw[1][1][1]);
}
else
{
Madd(g[is|0][1][1],nw[0][0][1]),Madd(g[is|0][1][1],nw[0][1][1]);
Madd(g[is|1][1][1],nw[1][0][1]),Madd(g[is|1][1][1],nw[1][1][1]);
}
}
}
}
}
for(int i=1;i<=cnt;++i)
{
Madd(ans,f[pre][i][1][0][0]),Madd(ans,f[pre][i][1][0][1]);
Madd(ans,f[pre][i][1][1][0]),Madd(ans,f[pre][i][1][1][1]);
}
write(ans);
}