#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <string>
#include <string.h>
#include <map>
#include <vector>
typedef long long LL ;
const int nodeSize = 2008 ;
const int alphaSize = 2 ;
const LL mod = 1000000009LL ;
void Mod(LL &res){
if(res < 0) res = (res + mod) % mod ;
while(res >= mod) res -= mod ;
}
struct AC{
int next[nodeSize][alphaSize] ;
int cnt[nodeSize] ;
int fail[nodeSize] ;
int root ;
int totel ;
void clear(){
totel = 0 ;
root = newNode() ;
memset(dp , -1 , sizeof(dp)) ;
}
int newNode(){
cnt[totel] = 0 ;
memset(next[totel] , 0 , sizeof(next[totel])) ;
return totel++ ;
}
void add(char *s){
int now = root ;
for(int i = 0 ; s[i] ; i++){
int son = s[i] - '0' ;
if(! next[now][son]) next[now][son] = newNode() ;
now = next[now][son] ;
}
cnt[now] = 1 ;
}
void buildAC(){
std::queue<int> q ;
fail[root] = root ;
for(int son = 0 ; son < alphaSize ; son++){
if(! next[root][son]) next[root][son] = root ;
else{
q.push(next[root][son]) ;
fail[next[root][son]] = root;
}
}
while(! q.empty()){
int now = q.front() ; q.pop() ;
if(cnt[fail[now]]) cnt[now] = 1 ;
for(int son = 0 ; son < alphaSize ; son++){
if(! next[now][son]) next[now][son] = next[fail[now]][son] ;
else{
fail[next[now][son]] = next[fail[now]][son] ;
q.push(next[now][son]) ;
}
}
}
}
int query(char *s){
int now = root ;
for(int i = 0 ; s[i] ; i++){
int d = s[i] - '0' ;
for(int j = 3 ; j >= 0 ; j--){
now = next[now][(d>>j) & 1] ;
int u = now ;
while(u != root){
if(cnt[u]) return 0 ;
u = fail[u] ;
}
}
}
return 1 ;
}
int state[nodeSize][10] ;
int getState(int s , int k){
if(cnt[s]) return -1 ;
for(int i = 3 ; i >= 0 ; i--){
if(cnt[next[s][(k>>i) & 1]]) return -1 ;
s = next[s][(k>>i) & 1] ;
}
return s ;
}
void preState(){
for(int s = 0 ; s < totel ; s++){
for(int k = 0 ; k <= 9 ; k++){
state[s][k] = getState(s , k) ;
}
}
}
int bit[208] ;
LL answer(char *s){
int len = strlen(s) ;
int pos = 0 ;
for(int i = len-1 ; i >= 0 ; i--) bit[pos++] = s[i] - '0' ;
return dfs(pos-1 , 1 , 0 , 1) ;
}
LL dp[208][2][2008] ;
LL dfs(int pos , int isLeadZore , int nowState , int isEnd){
if(pos == -1) return 1 ;
if(!isEnd && dp[pos][isLeadZore][nowState] != -1)
return dp[pos][isLeadZore][nowState] ;
LL res = 0 ;
if(isLeadZore)
res += dfs(pos-1 , 1 , nowState , isEnd && bit[pos] == 0) ;
else if(state[nowState][0] != -1)
res += dfs(pos-1 , 0 , state[nowState][0] , isEnd && bit[pos] == 0) ;
Mod(res) ;
int d = isEnd ? bit[pos] : 9 ;
for(int i = 1 ; i <= d ; i++){
if(state[nowState][i] != -1){
res += dfs(pos-1 , 0 , state[nowState][i] , isEnd && i == d) ;
Mod(res) ;
}
}
if(! isEnd) dp[pos][isLeadZore][nowState] = res ;
return res ;
}
};
AC ac ;
char word[208] , Lf[208] , Rt[208] ;
int main(){
int t , n ;
scanf("%d" , &t) ;
while(t--){
scanf("%d" , &n) ;
ac.clear() ;
while(n--){
scanf("%s" , word) ;
ac.add(word) ;
}
ac.buildAC() ;
ac.preState() ;
scanf("%s%s" , Lf , Rt) ;
LL res = ac.answer(Rt) - ac.answer(Lf) + ac.query(Lf) ;
Mod(res) ;
printf("%lld\n" , res) ;
}
return 0;
}
zoj3494AC自动机
最新推荐文章于 2019-08-19 21:01:00 发布