#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int each[10][4] = {0,0,0,0, 0,0,0,1, 0,0,1,0, 0,0,1,1, 0,1,0,0, 0,1,0,1, 0,1,1,0, 0,1,1,1, 1,0,0,0, 1,0,0,1};
const int N = 100, L = 21, T = 2, M = 205;
const int ND = N*L;
const int MOD = 1000000009;
int str[N][L], pa[M], pb[M];
int n;
int next[ND][T], fail[ND], acc[ND], B[ND], cnt;
int step[ND][10], total[M][ND], non[M];
void read(int *f){
char c; while(c=getchar(), c<'0'||c>'9');
f[f[0]=1] = c-'0'; while(c=getchar(), c>='0'&&c<='9') f[++f[0]] = c-'0';
}
void init(){
scanf("%d", &n);
for(int i=0; i<n; i++) read(str[i]);
read(pa); read(pb);
}
void construct(){
cnt = 0;
memset(next, 0, sizeof(int)*ND*T);
memset(fail, 0, sizeof(int)*ND);
memset(acc, 0, sizeof(int)*ND);
for(int i=0, p, j; i<n; i++){
for(p=0, j=1; j<=str[i][0]; j++) if(next[p][str[i][j]]) p = next[p][str[i][j]];
else next[p][str[i][j]] = ++cnt, p = cnt;
acc[p] = 1;
}
int hd(0), tl(0);
for(int i=0; i<T; i++) if(next[0][i]) B[++tl] = next[0][i];
while(hd<tl){
int x = B[++hd]; acc[x] |= acc[fail[x]];
for(int i=0; i<T; i++) if(next[x][i]){
fail[next[x][i]] = next[fail[x]][i];
B[++tl] = next[x][i];
} else next[x][i] = next[fail[x]][i];
}
}
void reverse(int *f){ for(int i=1; i<=f[0]/2; i++) swap(f[i], f[f[0]-i+1]); }
void dec(int *f){
int last = 1; while(!f[last]) ++last;
for(int i=1; i<last; i++) f[i] = 9; f[last]--;
if(f[f[0]]==0) --f[0];
}
void predp(int x){
/* step */
for(int i=0; i<=cnt; i++){
for(int num=0, p, j; num<10; num++) {
for(p=i, j=0; j<4 && !acc[p]; j++) p = next[p][each[num][j]];
step[i][num] = p;
}
}
/*total*/
memset(total, 0, sizeof(int)*M*ND);
for(int i=0; i<=cnt; i++) total[0][i] = !acc[i];
for(int ci=1; ci<=x; ci++) {
for(int i=0; i<=cnt; i++) if(!acc[i]) {
for(int num=0; num<10; num++) total[ci][i] = (total[ci][i] + total[ci-1][step[i][num]]) % MOD;
}
}
/*non*/
non[0] = 0;
for(int i=1; i<=x; i++){
non[i] = ((non[i-1] + total[i][0])%MOD - total[i-1][step[0][0]]) % MOD;
}
}
int dp(int *f){
int ret(non[f[0]-1]), p=0;
for(int i=f[0]; i; i--){
for(int num = (i==f[0])? 1 : 0; num < f[i]; num++ ) ret = (ret + total[i-1][step[p][num]]) % MOD;
p = step[p][f[i]];
if(acc[p]) break;
}
if(f[0]==0) ret = (ret + total[0][step[0][0]]) % MOD;
else ret = ((ret + total[0][p])%MOD + total[0][step[0][0]])%MOD;
return ret;
}
void maindo(){
reverse(pa), reverse(pb);
dec(pa);
predp(pb[0]);
int ans = ((dp(pb) - dp(pa)) % MOD + MOD ) % MOD;
printf("%d\n", ans);
}
void work(){
init();
construct();
maindo();
}
int main(){
freopen("bcd.in", "r", stdin);
freopen("bcd.out", "w", stdout);
int Tes;
scanf("%d", &Tes);
while(Tes-->0) work();
return 0;
}
【Aho-Corasick Automaton】
最新推荐文章于 2024-07-23 11:38:15 发布