#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define mxn 100020
struct trie {
int ch[mxn][128], fail[mxn], lst[mxn], cnt[mxn];
int sz;
int creat() {
memset( ch[sz], -1, sizeof( ch[sz] ) );
cnt[sz] = 0;
return sz++;
}
void init() {
memset( ch[0], -1, sizeof( ch[0] ) );
cnt[0] = 0;
sz = 1;
}
void insert( char *s, int val ) {
int t = 0;
for( int i = 0; s[i]; ++i ) {
int c = s[i];
if( ch[t][c] == -1 )
ch[t][c] = creat();
t = ch[t][c];
}
cnt[t] = val;
}
void build() {
queue<int> q;
fail[0] = 0;
for( int i = 0; i < 128; ++i ) {
if( ch[0][i] == -1 )
ch[0][i] = 0;
else {
fail[ch[0][i]] = 0;
q.push( ch[0][i] );
}
}
while( !q.empty() ) {
int t = q.front(); q.pop();
for( int i = 0; i < 128; ++i ) {
if( ch[t][i] == -1 )
ch[t][i] = ch[fail[t]][i];
else {
int nxt = ch[t][i];
fail[nxt] = ch[fail[t]][i];
lst[nxt] = cnt[fail[nxt]] ? fail[nxt]: lst[fail[nxt]];
q.push( nxt );
}
}
}
}
bool query( char *s, int num ) {
vector<int> g;
int t = 0;
for( int i = 0; s[i]; ++i ) {
int c = s[i];
t = ch[t][c];
int tmp = t;
while( tmp ) {
if( cnt[tmp] ) {
g.push_back( cnt[tmp] );
}
tmp = lst[tmp];
}
}
if( g.size() == 0 )
return 0;
printf( "web %d:", num );
sort( g.begin(), g.end() );
g.erase( unique( g.begin(), g.end() ), g.end() );
for( int i = 0; i < g.size(); ++i )
printf( " %d", g[i] );
puts( "" );
return 1;
}
void debug() {
for( int i = 0;i < sz; i++ ) {
printf( "id = %3d,fail = %3d,cnt = %3d,chi = [", i, fail[i], cnt[i] );
for( int j = 0; j < 26; j++ )
printf( "%2d",ch[i][j] );
printf( "]\n" );
}
}
}ac;
char s[100020];
int main() {
int n;
while( scanf( "%d", &n ) != EOF ) {
ac.init();
getchar();
for( int i = 1; i <= n; ++i ) {
gets( s );
ac.insert( s, i );
}
ac.build();
scanf( "%d", &n );
int ans = 0;
getchar();
for( int i = 1; i <= n; ++i ) {
gets( s );
if( ac.query( s, i ) )
ans++;
}
printf( "total: %d\n", ans );
}
return 0;
}
hdu 2896 ac自动机(last指针)
最新推荐文章于 2022-03-25 16:16:04 发布