Pagini recente » Cod sursa (job #1959728) | Cod sursa (job #1436588) | Cod sursa (job #1370958) | Cod sursa (job #766783) | Cod sursa (job #2448013)
#include <bits/stdc++.h>
using namespace std;
const int L_MAX = 1000002;
const int N_MAX = 102;
const int W_MAX = 10002;
const int BUFFER_SIZE = 1000002;
FILE* file = fopen("ahocorasick.in", "r");
ofstream fout ("ahocorasick.out");
char buffer[BUFFER_SIZE];
int pos = -1;
void read_buffer ()
{
fread(buffer, sizeof(char), BUFFER_SIZE, file);
}
char read ()
{
pos++;
if(pos >= BUFFER_SIZE)
{
read_buffer();
pos = 0;
}
return buffer[pos];
}
int read_int ()
{
char c;
while(iswspace(c = read()));
int x = 0;
while(isdigit(c))
{
x = x * 10 + c - '0';
c = read();
}
return x;
}
string read_str ()
{
char c;
while(iswspace(c = read()));
string s = "";
while(c >= 'a' && c <= 'z')
{
s += c;
c = read();
}
return s;
}
struct Trie
{
int index;
int ap;
Trie* sons[26];
Trie* maxPref;
int apSubstr;
Trie ()
{
index = 0;
for(int i = 0; i < 26; i++)
sons[i] = NULL;
ap = 0;
maxPref = NULL;
apSubstr = 0;
}
};
Trie* Root = new Trie();
void trieInsert (Trie* root, char* str, int index)
{
if(str[0] == '\0')
{
root->ap++;
if(root->index == 0)
root->index = index;
}
else
{
if(root->sons[str[0] - 'a'] == NULL)
root->sons[str[0] - 'a'] = new Trie();
trieInsert(root->sons[str[0] - 'a'], str + 1, index);
}
}
string a;
int n;
pair <string, int> w[N_MAX];
queue <Trie*> q;
vector <Trie*> order;
void bfs ()
{
Root->maxPref = Root;
q.push(Root);
while(!q.empty())
{
Trie* root = q.front();
order.push_back(root);
q.pop();
for(int i = 0; i < 26; i++)
if(root->sons[i] != NULL)
{
root->sons[i]->maxPref = root->maxPref;
while(root->sons[i]->maxPref != Root && root->sons[i]->maxPref->sons[i] == NULL)
root->sons[i]->maxPref = root->sons[i]->maxPref->maxPref;
if(root->sons[i]->maxPref->sons[i] != NULL && root != Root)
root->sons[i]->maxPref = root->sons[i]->maxPref->sons[i];
q.push(root->sons[i]);
}
}
}
int answer[N_MAX];
int answer1[N_MAX];
void getFreq ()
{
Trie* p = Root;
for(int i = 0; i < a.size(); i++)
{
while(p != Root && p->sons[a[i] - 'a'] == NULL)
p = p->maxPref;
if(p->sons[a[i] - 'a'] != NULL)
p = p->sons[a[i] - 'a'];
p->apSubstr++;
}
}
void getAnswer ()
{
reverse(order.begin(), order.end());
for(Trie* node : order)
{
node->maxPref->apSubstr += node->apSubstr;
answer[node->index] = node->apSubstr;
}
}
char str[W_MAX];
int main()
{
read_buffer();
a = read_str();
n = read_int();
for(int i = 1; i <= n; i++)
{
w[i].first = read_str();
w[i].second = i;
}
sort(w + 1, w + n + 1);
for(int i = 1; i <= n; i++)
{
strcpy(str, w[i].first.c_str());
trieInsert(Root, str, i);
}
bfs();
getFreq();
memset(answer, -1, sizeof(answer));
getAnswer();
for(int i = 1; i <= n; i++)
{
if(answer[i] == -1)
answer[i] = answer[i - 1];
answer1[w[i].second] = answer[i];
}
for(int i = 1; i <= n; i++)
fout << answer1[i] << "\n";
return 0;
}