hdu 2896 ac自动机(last指针)

来源:互联网 发布:notepad mac 破解 编辑:程序博客网 时间:2024/06/15 07:47
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <vector>using namespace std;#define mxn 100020struct 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;}

0 0