其他分享
首页 > 其他分享> > HDU_3065 病毒持续入侵中 ( AC自动机 )

HDU_3065 病毒持续入侵中 ( AC自动机 )

作者:互联网

题意
给定N个模板穿, 一个匹配串, 按格式输出N个模本串在匹配串中出现的次数

题解
用数组end记录出现次数

代码

#include <bits/stdc++.h>
using namespace std;
#define rg register 
#define sc scanf
#define pf printf 

const int MAXN = 1010*50+10;

char str[1010][100];
struct Trie {
	int nxt[MAXN][128], fail[MAXN], end[MAXN];
	int root, L;
	int newnode ( ) {
		for ( int i = 0; i < 128; i++ )
			nxt[L][i] = -1;
		end[L++] = -1;
		return L - 1;
	}
	void init ( ) {
		L = 0;
		root = newnode ( );
	}
	void insert ( char s[], int id ) {
		int len = strlen ( s );
		int now = root;
		for ( int i = 0; i < len; i++ ) {
			if ( nxt[now][s[i]] == -1 )
				nxt[now][s[i]] = newnode ( );
			now = nxt[now][s[i]];
		}
		end[now] = id;
	}
	void build ( ) {
		queue<int>Q;
		fail[root] = root;
		for ( int i = 0; i < 128; i++ )
			if ( nxt[root][i] == -1 )
				nxt[root][i] = root;
			else {
				fail[nxt[root][i]] = root;
				Q.push ( nxt[root][i] );
			}
		while ( !Q.empty ( ) ) {
			int now = Q.front ( );
			Q.pop ( );
			for ( int i = 0; i < 128; i++ )
				if ( nxt[now][i] == -1 )
					nxt[now][i] = nxt[fail[now]][i];
				else {
					fail[nxt[now][i]] = nxt[fail[now]][i];
					Q.push ( nxt[now][i] );
				}
		}
	}
	int num[1010];
	void query ( char buf[], int n ) {
		for ( int i = 0; i < n; i++ )
			num[i] = 0;
		int len = strlen ( buf );
		int now = root;
		for ( int i = 0; i < len; i++ ) {
			now = nxt[now][buf[i]];
			int temp = now;
			while ( temp != root ) {
				if ( end[temp] != -1 )
					num[end[temp]]++;
				temp = fail[temp];
			}
		}
		for ( int i = 0; i < n; i++ )
			if ( num[i] > 0 )
				pf ( "%s: %d\n", str[i], num[i] );
	}
	void debug ( ) {
		for ( int i = 0; i < L; i++ ) {
			pf ( "id = %3d ,fail = %3d ,end = %3d, chi = [", i, fail[i], end[i] );
			for ( int j = 0; j < 128; j++ )
				pf ( "%2d ", nxt[i][j] );
			pf ( "]\n" );
	}
}
};

char buf[2000010];
Trie ac;

int main ( ) {

	int n;
	while ( sc ( "%d", &n ) == 1 ) {

		ac.init ( );

		for ( int i = 0; i < n; i++ ) {
			sc ( "%s", str[i] );
			ac.insert ( str[i], i );
		}

		ac.build ( );

		sc ( "%s", buf );

		ac.query ( buf, n );

	}






	return 0;
}

标签:nxt,HDU,int,AC,++,3065,fail,now,root
来源: https://blog.csdn.net/weixin_44510468/article/details/101387699