Pagini recente » Cod sursa (job #1803253) | Cod sursa (job #89705) | Cod sursa (job #2262748) | Cod sursa (job #1227554) | Cod sursa (job #1351325)
#include<fstream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
ifstream in("ahocorasick.in");
ofstream out("ahocorasick.out");
struct trie{
trie *c[26],*tata;
trie *fail;
vector<trie*> to;
vector<int> is;
int f,fs,s;
vector<int> F,FS,S;
char id;
trie(){
tata=fail=NULL;f=s=fs=0;
for(int i=0;i<='z'-'a';i++) c[i]=NULL;
to.clear(),is.clear(),id='$';
}
};
trie* R=new trie;
char A[1000002],B[10002];
int N,n,m,f[102];
vector<int> FF[10001];
queue<trie*> q;
void dfs(trie* n){
if(!n->fs) q.push(n);
for(vector<trie*>::iterator it=n->to.begin();it!=n->to.end();++it) dfs(*it);
}
int main(){
in.getline(A+1,1000001); n=strlen(A+1);
in>>N; in.get();
for(int i=1;i<=N;i++){
in.getline(B+1,10001); m=strlen(B+1);
trie* wh=R;
for(int j=1;j<=m;j++){
if(wh->c[B[j]-'a']) wh=wh->c[B[j]-'a'];
else{
trie* fiu=wh->c[B[j]-'a']=new trie;
wh->to.push_back(fiu);
fiu->tata=wh;
fiu->id=B[j];
wh=fiu;
}
}
wh->is.push_back(i);
}
R->fail=R;
for(vector<trie*>::iterator it=R->to.begin();it!=R->to.end();++it) q.push(*it);
while(!q.empty()){
trie* x=q.front(); q.pop();
trie* y=x->tata->fail;
while(y!=R && !y->c[x->id-'a']) y=y->fail;
if(y->c[x->id-'a']) x->fail=y->c[x->id-'a'];
else x->fail=y;
if(x->fail==x) x->fail=x->tata;
x->fail->fs++;
for(vector<trie*>::iterator it=x->to.begin();it!=x->to.end();++it) q.push(*it);
}
trie* wh=R;
for(int i=1;i<=n;i++){
while(wh!=R && !wh->c[A[i]-'a']) wh=wh->fail;
if(wh->c[A[i]-'a']) wh=wh->c[A[i]-'a'];
wh->f++;
wh->F.push_back(i);
}
dfs(R);
while(!q.empty()){
trie *x=q.front(); q.pop();
x->s+=x->f;
x->S.insert(x->S.end(),x->F.begin(),x->F.end());
for(vector<int>::iterator it=x->is.begin();it!=x->is.end();++it){
f[*it]+=x->s;
FF[*it].insert(FF[*it].end(),x->S.begin(),x->S.end());
}
x->fail->s+=x->s;
x->fail->S.insert(x->fail->S.end(),x->S.begin(),x->S.end());
x->fail->fs--;
if(!x->fail->fs) q.push(x->fail);
}
//for(int i=1;i<=N;i++) out<<f[i]<<'\n';
for(int i=1;i<=N;i++){
out<<FF[i].size()<<'\n';
//for(vector<int>::iterator it=FF[i].begin();it!=FF[i].end();++it) out<<*it<<' ';out<<'\n';
}
return 0;
}