Pagini recente » Cod sursa (job #2557026) | Cod sursa (job #51382) | Cod sursa (job #1050287) | Cod sursa (job #43796) | Cod sursa (job #2266419)
#include <bits/stdc++.h>
using namespace std;
const int SIGMA = 30;
const int NMAX = 1000000;
const int LENMAX = 10000;
char a[NMAX + 5], aux[LENMAX + 5];
struct Trie {
int cnt;
Trie* link;
Trie* son[SIGMA];
vector<int> words;
Trie() {
words.clear();
link = NULL;
cnt = 0;
for(int i = 0; i < SIGMA; i ++)
son[i] = NULL;
}
};
Trie* root = new Trie();
Trie* cur;
inline bool ischar(char c) {
if('a' <= c && c <= 'z')
return 1;
return 0;
}
void addTrie(Trie* node, int i, int ind) {
if(!ischar(aux[i]))
node -> words.push_back(ind);
else {
if(node -> son[aux[i] - 'a'] == NULL)
node -> son[aux[i] - 'a'] = new Trie();
addTrie(node -> son[aux[i] - 'a'], i + 1, ind);
}
}
vector<Trie*> nodelist;
void buildLinks() {
queue<Trie*> q;
for(int i = 0; i < SIGMA; i ++)
if(root -> son[i] != NULL) {
root -> son[i] -> link = root;
q.push(root -> son[i]);
}
while(q.size()) {
Trie* node = q.front();
q.pop();
nodelist.push_back(node);
for(int i = 0; i < SIGMA; i ++) {
if(node -> son[i] != NULL) {
Trie* pretender = node;
do {
pretender = pretender -> link;
} while(pretender != root && (pretender -> son[i] == NULL));
if(pretender -> son[i] != NULL)
pretender = pretender -> son[i];
node -> son[i] -> link = pretender;
q.push(node -> son[i]);
}
}
}
}
int main() {
FILE *in, *out;
in = fopen("ahocorasick.in", "r");
out = fopen("ahocorasick.out", "w");
fgets(a, NMAX + 3, in);
int n;
fscanf(in, "%d\n", &n);
for(int i = 1; i <= n; i ++) {
for(int j = 0; j < LENMAX + 3; j ++)
aux[j] = '\n';
fgets(aux, LENMAX + 3, in);
addTrie(root, 0, i);
}
buildLinks();
cur = root;
int i = 0;
while(ischar(a[i])) {
while(cur != root && (cur -> son[a[i] - 'a'] == NULL))
cur = cur -> link;
if(cur -> son[a[i] - 'a'] != NULL)
cur = cur -> son[a[i] - 'a'];
cur -> cnt ++;
i ++;
}
vector<int> sol(n + 1, 0);
for(int i = nodelist.size() - 1; i >= 0; i --) {
Trie* node = nodelist[i];
node -> link -> cnt += node -> cnt;
for(auto it : node -> words) {
sol[it] += node -> cnt;
}
}
for(int i = 1; i <= n; i ++)
fprintf(out, "%d\n", sol[i]);
return 0;
}