HDU 2896 病毒侵袭 [AC自动机]
http://acm.hdu.edu.cn/showproblem.php?pid=2896
题意:给n个模式串m个文本串,问每个文本串里出现了哪些模式串。每个模式串唯一。
ac自动机中,用end数组把模式串的id记录下来就好。
#include<cassert>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<queue>
#include<map>
using namespace std;
#define rep(i,f,t) for(int i = (f), _end = (t); i <= _end; ++i)
#define dep(i,f,t) for(int i = (f), _end = (t); i >= _end; --i)
#define clr(c,x) memset(c,x,sizeof(c));
#define debug(x) cout<<"debug "<<x<<endl;
const int INF = 0x3f3f3f3f;
typedef long long int64;
inline int RD(){ int res; scanf("%d",&res); return res; }
#define Rush for(int casn = RD(), cas = 1; cas <= casn; ++cas)
//*******************************************************************************
const int maxn = 501;
struct Trie{
int next[maxn*200][128];
int fail[maxn*200];
int end[maxn*200];
int sz;
void init(){
sz = 0;
clr(next[0],0);
}
int newnode(){
++sz;
clr(next[sz],0);
fail[sz] = end[sz] = 0;
return sz;
}
void insert(char *s, int id){
int u = 0;
while(*s){
int &v = next[u][*s];
if(!v) v = newnode();
u = v;
++s;
}
end[u] = id;
}
void build(){
queue<int> Q;
rep(i,1,127){
if(next[0][i])Q.push(next[0][i]);
}
while(!Q.empty()){
int u = Q.front();
Q.pop();
int fu = fail[u];
rep(c,1,127){
int &v = next[u][c];
if(v){
Q.push(v);
fail[v] = next[fu][c];
}else{
v = next[fu][c];
}
}
}
}
void query(char *s, vector<int> &res){
int u = 0;
while(*s){
u = next[u][*s];
int k = u;
while(k){
if(end[k]){
res.push_back(end[k]);
}
k = fail[k];
}
++s;
}
sort(res.begin(),res.end());
}
}ac;
char str[10005];
int main(){
int n,m;
while(~scanf("%d",&n)){
ac.init();
rep(i,1,n){
scanf("%s",str);
ac.insert(str,i);
}
ac.build();
scanf("%d",&m);
vector<int> res;
int tot = 0;
rep(i,1,m){
scanf("%s",str);
res.clear();
ac.query(str,res);
if(!res.empty()){
++tot;
printf("web %d:",i);
rep(j,0,res.size()-1){
printf(" %d",res[j]);
}
printf("\n");
}
}
printf("total: %d\n",tot);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。