Pagini recente » Cod sursa (job #939256) | Cod sursa (job #353866) | Cod sursa (job #2635652) | Cod sursa (job #1451348) | Cod sursa (job #3304077)
/*#include <fstream>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
struct node
{
node *fii[26];
node *fail;
vector<int> output;
};
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
int n;
string s, x;
node *root = new node();
int frec[105];
void adauga(string x, int ind)
{
node *nod = root;
for(auto it: x)
{
if(nod->fii[it - 'a'] == NULL)
{
nod->fii[it - 'a'] = new node();
}
nod = nod->fii[it - 'a'];
}
nod->output.push_back(ind);
}
void bfs()
{
queue<node*> q;
root->fail = root;
for(int i = 0; i<26; i++)
{
if(root->fii[i] != NULL)
{
root->fii[i]->fail = root;
q.push(root->fii[i]);
}
}
while(!q.empty())
{
node *nod = q.front();
q.pop();
//cout<<"A";
for(int i = 0; i<26; i++)
{
if(nod->fii[i] == NULL)
{
continue;
}
node *it = nod->fii[i];
q.push(it);
node *f = nod->fail;
while(f != root && f->fii[i] == NULL)
{
f = f->fail;
}
if(f->fii[i] != NULL)
{
it->fail = f->fii[i];
}
else
{
it->fail = root;
}
for(auto ind: it->fail->output)
{
it->output.push_back(ind);
}
}
}
}
int main()
{
in>>s;
in>>n;
for(int i = 1; i<=n; i++)
{
in>>x;
adauga(x, i);
}
bfs();
int i = 0;
node *nod = root;
while(i < s.size())
{
if(nod->fii[s[i] - 'a'] != NULL)
{
nod = nod->fii[s[i] - 'a'];
i++;
for(auto it: nod->output)
{
frec[it]++;
}
}
else
{
if(nod == root)
{
i++;
}
else
{
nod = nod->fail;
}
}
}
for(int i = 1; i<=n; i++)
{
out<<frec[i]<<'\n';
}
return 0;
}*/
//un test mai cct ultimul (solutia de mai sus ia 95)
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
using namespace std;
static const int MAXS = 1000000 + 5;
static const int ALPHA = 26;
int nxt[MAXS][ALPHA], fail[MAXS];
int node_cnt = 1; // 0 = root
int endNode[105]; // starea în care se termină pattern-ul i
long long cntState[MAXS];
int main(){
// I/O din fișiere și STDIO rapid
freopen("ahocorasick.in","r",stdin);
freopen("ahocorasick.out","w",stdout);
static char A[1000005];
int n;
// Citim textul și numărul de pattern‑uri
scanf("%s", A);
scanf("%d", &n);
// Construim trie‑ul și reținem endNode pentru fiecare pattern
for(int id = 1; id <= n; id++){
static char s[10005];
scanf("%s", s);
int u = 0;
for(int i = 0; s[i]; i++){
int c = s[i] - 'a';
if(!nxt[u][c]) nxt[u][c] = node_cnt++;
u = nxt[u][c];
}
endNode[id] = u;
}
// BFS pentru fail & completare tranziții, păstrăm ordinea în bfsOrd
vector<int> bfsOrd;
queue<int> q;
// nivel 1
for(int c = 0; c < ALPHA; c++){
int v = nxt[0][c];
if(v){
fail[v] = 0;
q.push(v);
bfsOrd.push_back(v);
}
}
while(!q.empty()){
int u = q.front(); q.pop();
for(int c = 0; c < ALPHA; c++){
int v = nxt[u][c];
if(v){
int f = fail[u];
while(f && !nxt[f][c]) f = fail[f];
fail[v] = nxt[f][c];
q.push(v);
bfsOrd.push_back(v);
} else {
nxt[u][c] = nxt[ fail[u] ][c];
}
}
}
// Parcurgem textul și înregistrăm vizitele în cntState
int cur = 0;
for(int i = 0; A[i]; i++){
int c = A[i] - 'a';
cur = nxt[cur][c];
cntState[cur]++;
}
// Propagăm înapoi pe fail, în ordinea inversă BFS
for(int i = (int)bfsOrd.size()-1; i >= 0; --i){
int u = bfsOrd[i];
cntState[ fail[u] ] += cntState[u];
}
// Pentru fiecare pattern, răspunsul e cntState[endNode[id]]
for(int id = 1; id <= n; id++){
printf("%lld\n", cntState[ endNode[id] ]);
}
return 0;
}