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 }

 

posted @ 2013-11-01 10:18  degree  阅读(164)  评论(0编辑  收藏  举报