hdu 2896 ac自动机(last指针)

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值