题目链接:https://vjudge.net/problem/POJ-1625
Time Limit: 5000MS | Memory Limit: 10000K | |
Total Submissions: 10870 | Accepted: 2979 |
Description
But after recent election of Mr. Grass Jr. as Freeland president some words offending him were declared unprintable and all sentences containing at least one of them were forbidden. The sentence S contains a word W if W is a substring of S i.e. exists such k >= 1 that S[k] = W[1], S[k+1] = W[2], ...,S[k+len(W)-1] = W[len(W)], where k+len(W)-1 <= M and len(W) denotes length of W. Everyone who uses a forbidden sentence is to be put to jail for 10 years.
Find out how many different sentences can be used now by freelanders without risk to be put to jail for using it.
Input
The second line contains exactly N different characters -- the letters of the Freish alphabet (all with ASCII code greater than 32).
The following P lines contain forbidden words, each not longer than min(M, 10) characters, all containing only letters of Freish alphabet.
Output
Sample Input
2 3 1 ab bb
Sample Output
5
Source
题意:
给出p个单词,求长度为m且不含有已给单词的字符串有多少个?其中字母表有n个字母。
题解:
与POJ2278 DNA Sequence无异,只不过此题没有取模,而答案可能很大,所以用到高精度。而且字符串长度较小,可以直接用动态规划进行求解,而不需要用到矩阵进行加速。
代码如下:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <cmath> 7 #include <queue> 8 #include <stack> 9 #include <map> 10 #include <string> 11 #include <set> 12 using namespace std; 13 typedef long long LL; 14 const double EPS = 1e-6; 15 const int INF = 2e9; 16 const LL LNF = 9e18; 17 const int MOD = 1e5; 18 const int MAXN = 50*50+10; 19 20 struct BigInt 21 { 22 const static int mod = 10000; 23 const static int DLEN = 4; 24 int a[100],len; 25 BigInt() 26 { 27 memset(a,0,sizeof(a)); 28 len = 1; 29 } 30 BigInt(int v) 31 { 32 memset(a,0,sizeof(a)); 33 len = 0; 34 do 35 { 36 a[len++] = v%mod; 37 v /= mod; 38 }while(v); 39 } 40 BigInt operator +(const BigInt &b)const 41 { 42 BigInt res; 43 res.len = max(len,b.len); 44 for(int i = 0;i <= res.len;i++) 45 res.a[i] = 0; 46 for(int i = 0;i < res.len;i++) 47 { 48 res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0); 49 res.a[i+1] += res.a[i]/mod; 50 res.a[i] %= mod; 51 } 52 if(res.a[res.len] > 0)res.len++; 53 return res; 54 } 55 void output() 56 { 57 printf("%d",a[len-1]); 58 for(int i = len-2;i >=0 ;i--) 59 printf("%04d",a[i]); 60 printf("\n"); 61 } 62 }; 63 64 BigInt dp[2][MAXN]; 65 int M[128]; 66 struct Trie 67 { 68 int sz, base; 69 int next[MAXN][50], fail[MAXN], end[MAXN]; 70 int root, L; 71 int newnode() 72 { 73 for(int i = 0; i<sz; i++) 74 next[L][i] = -1; 75 end[L++] = false; 76 return L-1; 77 } 78 79 void init(int _sz, int _base) 80 { 81 sz = _sz; 82 base = _base; 83 L = 0; 84 root = newnode(); 85 } 86 void insert(char buf[]) 87 { 88 int len = strlen(buf); 89 int now = root; 90 for(int i = 0; i<len; i++) 91 { 92 if(next[now][M[buf[i]]] == -1) next[now][M[buf[i]]] = newnode(); 93 now = next[now][M[buf[i]]]; 94 } 95 end[now] |= true; 96 } 97 void build() 98 { 99 queue<int>Q; 100 fail[root] = root; 101 for(int i = 0; i<sz; i++) 102 { 103 if(next[root][i] == -1) next[root][i] = root; 104 else fail[next[root][i]] = root, Q.push(next[root][i]); 105 } 106 while(!Q.empty()) 107 { 108 int now = Q.front(); 109 Q.pop(); 110 end[now] |= end[fail[now]]; 111 for(int i = 0; i<sz; i++) 112 { 113 if(next[now][i] == -1) next[now][i] = next[fail[now]][i]; 114 else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]); 115 } 116 } 117 } 118 119 void query(int len) 120 { 121 for(int i = 0; i<=1; i++) 122 for(int j = 0; j<L; j++) 123 dp[i][j] = 0; 124 125 int cur = 0; 126 dp[cur][root] = 1; 127 for(int i = 0; i<len; i++) 128 { 129 for(int j = 0; j<L; j++) 130 dp[cur^1][j] = 0; 131 for(int j = 0; j<L; j++) 132 { 133 if(end[j]) continue; 134 for(int k = 0; k<sz; k++) 135 { 136 if(end[next[j][k]]) continue; 137 dp[cur^1][next[j][k]] = dp[cur^1][next[j][k]] + dp[cur][j]; 138 } 139 } 140 cur ^= 1; 141 } 142 143 BigInt ret = 0; 144 for(int i = 0; i<L; i++) 145 ret = ret + dp[cur][i]; 146 ret.output(); 147 } 148 }; 149 150 Trie ac; 151 char buf[MAXN]; 152 int main() 153 { 154 int n, m, p; 155 while(scanf("%d%d%d", &n,&m,&p)!=EOF) 156 { 157 ac.init(n, 0); 158 scanf("%s", buf); 159 for(int i = 0; buf[i]; i++) 160 M[buf[i]] = i; 161 for(int i = 1; i<=p; i++) 162 { 163 scanf("%s", buf); 164 ac.insert(buf); 165 } 166 ac.build(); 167 ac.query(m); 168 } 169 }