Passwords
ac自动机 + DP
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int sigma = 26; 4 const int maxnode = 1010; 5 const int mod = 1000003; 6 int dp[21][maxnode][8]; 7 struct AC{ 8 int ch[maxnode][sigma]; 9 int f[maxnode]; 10 int mc[maxnode]; 11 int sz; 12 int yy[11]; 13 14 void init(){ 15 memset(ch[0], 0, sizeof(ch[0])); 16 memset(mc, 0, sizeof(mc)); 17 memset(yy, -1, sizeof(yy)); 18 sz = 1; 19 yy[0] = 'o' - 'a'; 20 yy[1] = 'i' - 'a'; 21 yy[3] = 'e' - 'a'; 22 yy[5] = 's' - 'a'; 23 yy[7] = 't' - 'a'; 24 } 25 26 int idx(char c) { 27 return c-'a'; 28 } 29 30 void insert(char *s) { 31 int n = strlen(s), u = 0; 32 for(int i = 0; i < n; i++){ 33 int c = idx(s[i]); 34 if(!ch[u][c]){ 35 memset(ch[sz], 0, sizeof(ch[sz])); 36 ch[u][c] = sz++; 37 } 38 u = ch[u][c]; 39 } 40 mc[u] = 1; 41 } 42 43 void getfail(){ 44 queue<int> q; 45 f[0] = 0; 46 for(int c = 0; c < sigma; c++){ 47 int u = ch[0][c]; 48 if(u) { 49 q.push(u); 50 f[u] = 0; 51 } 52 } 53 while(!q.empty()){ 54 int r = q.front(); 55 q.pop(); 56 for(int c = 0; c < sigma; c++){ 57 int u = ch[r][c]; 58 if(!u){ 59 ch[r][c] = ch[f[r]][c]; 60 continue; 61 } 62 q.push(u); 63 int v = f[r]; 64 while(v && !ch[v][c]) v = f[v]; 65 f[u] = ch[v][c]; 66 mc[u] |= mc[f[u]]; 67 } 68 } 69 } 70 }ac; 71 72 void add(int &a, int b){ 73 a = a+b; 74 if(a < 0) a += mod; 75 if(a >= mod) a -= mod; 76 } 77 78 void solve(int a, int b) { 79 memset(dp, 0, sizeof(dp)); 80 dp[0][0][0] = 1; 81 for(int i = 1; i <= b; i++){ 82 for(int j = 0; j < ac.sz; j++){ 83 if(ac.mc[j]) continue; 84 for(int k = 0; k < 8; k++){ 85 // if(dp[i-1][j][k]==0) continue; 86 for(int c = 0; c < sigma; c++){ 87 int u = ac.ch[j][c]; 88 if(ac.mc[u]) continue; 89 add(dp[i][u][k|(1<<0)], dp[i-1][j][k]); 90 add(dp[i][u][k|(1<<1)], dp[i-1][j][k]); 91 } 92 for(int c = 0; c < 10; c++){ 93 if(ac.yy[c] == -1){ 94 add(dp[i][0][k|(1<<2)], dp[i-1][j][k]); 95 } else { 96 int u = ac.ch[j][ac.yy[c]]; 97 if(ac.mc[u]) continue; 98 add(dp[i][u][k|(1<<2)], dp[i-1][j][k]); 99 } 100 } 101 } 102 } 103 } 104 int ans = 0; 105 for(int i = a; i <= b; i++){ 106 for(int j = 0; j < ac.sz; j++){ 107 add(ans, dp[i][j][7]); 108 } 109 } 110 printf("%d ", ans); 111 } 112 113 int main(){ 114 int a, b, n; 115 // freopen("in.txt", "r", stdin); 116 scanf("%d %d %d", &a, &b, &n); 117 ac.init(); 118 char s[21]; 119 for(int i = 0; i < n; i++){ 120 scanf("%s", s); 121 ac.insert(s); 122 } 123 ac.getfail(); 124 solve(a, b); 125 return 0; 126 }