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