http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430
先把base64编码转化为正常编码,然后AC自动机匹配
参考了http://blog.csdn.net/gatevin/article/details/41214249的代码风格,感觉这个AC自动机比自己之前的好上不少
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
using namespace std;
const int NODE_SIZE = 512*65;
const int SIG_SIZE = 265;
const int VIRUS_NUMBER = 515;
const int MAX_LEN = 3050;
int n;
struct Trie{
int next[NODE_SIZE][SIG_SIZE], fail[NODE_SIZE], end[NODE_SIZE];
int L, root;
bool vis[VIRUS_NUMBER];
int newnode(){
for (int i = 0; i < SIG_SIZE; i++)
next[L][i] = -1;
end[L++] = 0;
return L-1;
}
void init(){
L = 0;
root = newnode();
return ;
}
void Insert(int* in, int id){
int now = root;
for (; *in != -1; in++){
if (next[now][*in] == -1)
next[now][*in] = newnode();
now = next[now][*in];
}
end[now] = id;
}
void buildFail(){
fail[root] = root;
queue<int> q;
q.push(root);
while(!q.empty()){
int now = q.front();
q.pop();
for (int i = 0; i < SIG_SIZE; i++)
if (next[now][i] == -1)
next[now][i] = now == root ? root : next[fail[now]][i];
else{
fail[next[now][i]] = now == root ? root : next[fail[now]][i];
q.push(next[now][i]);
}
}
return ;
}
void query(int *in){
int now = root;
memset(vis, false, sizeof(vis));
for (; *in != -1; in++){
now = next[now][*in];
int tmp = now;
while(tmp != root){
if (end[tmp]) vis[end[tmp]] = true;
tmp = fail[tmp];
}
}
int res = 0;
for (int i = 1; i <= n; i++)
if (vis[i]) res++;
cout << res << endl;
}
};
int value[MAX_LEN];
char s[MAX_LEN];
map<char, int> mp;
void trans(){
int len = strlen(s);
int vpos, spos;
vpos = spos = 0;
int t[5];
for (; spos + 3 < len; spos += 4){
for (int i = 1; i < 5; i++)
t[i] = mp[s[spos+i-1]];
value[vpos++] = (t[1] << 2) + (t[2] >> 4);
if (t[3] != -1)
value[vpos++] = ((t[2]%(1<<4)) << 4) + (t[3] >> 2);
if (t[4] != -1)
value[vpos++] = ((t[3]%(1<<2)) << 6) + t[4];
}
value[vpos] = -1;
return ;
}
Trie Aho;
int main(){
//std::ios::sync_with_stdio(false);
for (int i = 0; i < 26; i++)
mp['A'+i] = i;
for (int i = 26; i < 52; i++)
mp['a'+i-26] = i;
for (int i = 52; i < 62; i++)
mp['0'+i-52] = i;
mp['+'] = 62; mp['/'] = 63;
mp['='] = -1;
while(cin >> n){
Aho.init();
for (int i = 1; i <= n; i++){
cin >> s;
trans();
Aho.Insert(value, i);
}
Aho.buildFail();
int m;
cin >> m;
while(m--){
cin >> s;
trans();
Aho.query(value);
}
cout << endl;
}
return 0;
}