ZOJ 3430 AC自动机
题目链接http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430
这题主要就是转码有点复杂。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <cctype> 6 #include <vector> 7 #include <stack> 8 #include <queue> 9 #include <map> 10 #include <algorithm> 11 #include <iostream> 12 #include <string> 13 #include <set> 14 #define X first 15 #define Y second 16 #define sqr(x) (x)*(x) 17 #pragma comment(linker,"/STACK:102400000,102400000") 18 using namespace std; 19 const double PI = acos(-1.0); 20 map<int, int>::iterator it; 21 typedef long long LL ; 22 template<typename T> void checkmin(T &x, T y) {x = min(x, y);} 23 template<typename T> void checkmax(T &x, T y) {x = max(x, y);} 24 25 const int MAX_NODE = 521 * 64 ; 26 const int CHILD_NUM = 256; 27 28 29 class ACAutomaton { 30 private: 31 int chd[MAX_NODE][CHILD_NUM]; 32 int fail[MAX_NODE]; 33 int val[MAX_NODE]; 34 int Q[MAX_NODE]; 35 int sz; 36 public: 37 void Initialize() { 38 fail[0] = 0; 39 } 40 void Reset() { 41 sz = 1; 42 memset(chd[0], -1, sizeof(chd[0])); 43 } 44 void Insert(int *s, int key, int n) { 45 int q = 0; 46 for(int i = 0; i < n; ++i) { 47 int c = s[i]; 48 if(chd[q][c] == -1) { 49 memset(chd[sz], -1, sizeof(chd[sz])); 50 val[sz] = 0; 51 chd[q][c] = sz++; 52 if(sz == MAX_NODE)while(1); 53 } 54 q = chd[q][c]; 55 } 56 val[q] = key; 57 } 58 void Construct() { 59 int *s = Q, *e = Q; 60 for(int i = 0; i < CHILD_NUM; ++i) { 61 if(~chd[0][i]) { 62 fail[ chd[0][i] ] = 0; 63 *e++ = chd[0][i]; 64 } 65 } 66 while(s != e) { 67 int r = *s++; 68 for(int i = 0; i < CHILD_NUM; ++i) { 69 int u = chd[r][i]; 70 if(~u) { 71 *e++ = u; 72 int v = fail[r]; 73 while(chd[v][i] == -1 && v)v = fail[v]; 74 fail[u] = chd[v][i] == -1 ? 0 : chd[v][i]; 75 } 76 } 77 } 78 } 79 int Query(int *s, int n) { 80 int q = 0; 81 set<int> st; 82 int ret = 0; 83 for(int i = 0; i < n ; ++i) { 84 int c = s[i]; 85 //printf("%c:\n", *s); 86 while(chd[q][c] == -1 && q)q = fail[q]; 87 q = chd[q][c]; 88 if(q == -1)q = 0; 89 int p = q; 90 while(p) { 91 if(val[p]) { 92 //printf("val[%d]=%d\n", p, val[p]); 93 st.insert(val[p]); 94 } 95 p = fail[p]; 96 } 97 } 98 ret = st.size(); 99 return ret; 100 } 101 } AC; 102 103 char mp[256]; 104 105 void init() { 106 for(int i = 0; i < 26; ++i) { 107 mp['A'+i] = i; 108 mp['a'+i] = 26 + i; 109 } 110 for(int i = 0; i < 10; ++i) { 111 mp['0'+i] = i + 52; 112 } 113 mp['+'] = 62; 114 mp['/'] = 63; 115 } 116 117 string dtos(int d) { 118 string ret = ""; 119 for(int i = 5; i >= 0; --i) { 120 if((1 << i)&d)ret += '1'; 121 else ret += '0'; 122 } 123 return ret; 124 } 125 126 vector<int> Transfor(char *s) { 127 int n = strlen(s); 128 string ans = ""; 129 vector<int> ret; 130 int cut = 0; 131 if(s[n-1] == '=') { 132 if(n > 1 && s[n-2] == '=') { 133 n -= 2; 134 cut = 4; 135 } 136 else { 137 --n; 138 cut = 2; 139 } 140 } 141 for(int i = 0; i < n; ++i) { 142 ans += dtos(mp[ s[i] ]); 143 } 144 while(cut--) { 145 ans.erase(ans.begin() + ans.size() - 1); 146 } 147 int d = 0; 148 //if((ans.size() % 8) != 0)while(1); 149 for(int i = 0; i < ans.size(); ++i) { 150 d |= (ans[i] == '1'); 151 if(i % 8 == 7) { 152 ret.push_back(d); 153 d = 0; 154 } 155 d <<= 1; 156 } 157 //for(int i = 0; i < ans.size(); ++i)printf("%3c", ans[i]); puts(""); 158 return ret; 159 } 160 161 char s[2056]; 162 int pat[2048*6+3]; 163 int main() { 164 init(); 165 /* 166 char s[] = "aGVsbG8="; 167 vector<char> tmp = Transfor(s); 168 for(int j = 0; j < tmp.size(); ++j) { 169 pat[j] = tmp[j]; 170 } 171 pat[ tmp.size()] = '\0'; 172 printf("%s\n", pat); 173 */ 174 int n, m; 175 AC.Initialize(); 176 while(~scanf("%d", &n)) { 177 AC.Reset(); 178 for(int i = 0; i < n; ++i) { 179 scanf("%s", s); 180 vector<int> tmp = Transfor(s); 181 for(int j = 0; j < tmp.size(); ++j) { 182 pat[j] = tmp[j]; 183 } 184 //printf("%s\n", pat); 185 AC.Insert(pat, i + 1, (int)tmp.size()); 186 } 187 AC.Construct(); 188 scanf("%d", &m); 189 for(int i = 0; i < m; ++i) { 190 scanf("%s", s); 191 vector<int> tmp = Transfor(s); 192 for(int j = 0; j < tmp.size(); ++j) { 193 pat[j] = tmp[j]; 194 } 195 //printf("%s\n", pat); 196 int res = AC.Query(pat, (int)tmp.size()); 197 printf("%d\n", res); 198 } 199 puts(""); 200 } 201 return 0; 202 }