AC自动机模板+例题(HDU2896+HDU3065+HDU2222)

病毒侵袭中(HDU2896)

AC自动机模板+例题(HDU2896+HDU3065+HDU2222)_第1张图片

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PII pair 
#define PSS pair
#define VINT vector 
#define fi first
#define se second
#define mkp make_pair
#define Pque priority_queue
#define pb push_back
using namespace std;
typedef long long LL;
const int maxn = 1e5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int n, m, tot;
char ss[maxn + 5];
bool vis[maxn + 5];
int fail[maxn + 5], trie[maxn + 5][130];
int bianhao[maxn + 5];//当前结束位置的病毒编号

void getfail(){
	queue q;
	for(int i = 0; i <= 128; i++){
		if(trie[0][i]){
			fail[trie[0][i]] = 0;
			q.push(trie[0][i]);
		}
	}
	while(!q.empty()){
		int now = q.front(); q.pop();
		for(int i = 0; i <= 128; i++){
			if(trie[now][i]){
				fail[trie[now][i]] = trie[fail[now]][i];
				q.push(trie[now][i]);
			}
			else trie[now][i] = trie[fail[now]][i];
		}
	}
	return;
}

int main(){
	scanf("%d", &n);
	for(int i = 1; i <= n; i++){
		scanf(" %s", ss); 
		int root = 0;
		int len = strlen(ss);
		for(int j = 0; j < len; j++){
			if(trie[root][ss[j]] == 0) trie[root][ss[j]] = ++tot;
			root = trie[root][ss[j]];
		}
		bianhao[root] = i;//记录编号
	}
	getfail();
	scanf("%d", &m);
	tot = 0;
	for(int i = 1; i <= m; i++){
		scanf(" %s", ss);
		memset(vis, 0, sizeof(vis));
		int len = strlen(ss);
		int now = 0, cnt = 0;
		int tmp[5] = {0}, ans[5] = {0};
		for(int j = 0; j < len; j++){
			now = trie[now][ss[j]];
			for(int k = now; k && !vis[k]; k = fail[k]){
				if(bianhao[k]){
					cnt++;
					tmp[cnt] = k;
					ans[cnt] = bianhao[k];
					break;
				}
				vis[k] = 1;
			}
			if(cnt == 3) break;
		}
		if(cnt != 0){
			sort(ans + 1, ans + cnt + 1);
			printf("web %d:", i);
			for(int j = 1; j <= cnt; j++){
				printf(" %d", ans[j]);
			}
			printf("\n");
			tot++;
		}
	}
	printf("total: %d\n", tot);
	return 0;
}

病毒持续侵袭中(HDU3065)

AC自动机模板+例题(HDU2896+HDU3065+HDU2222)_第2张图片

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PII pair 
#define PSS pair
#define VINT vector 
#define fi first
#define se second
#define mkp make_pair
#define Pque priority_queue
#define pb push_back
using namespace std;
typedef long long LL;
const int maxn = 5e4;
const int maxm = 2e6;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;

int n, m, tot;
char s[1005][55];
char ss[maxm + 5];
int fail[maxn + 5], trie[maxn + 5][30];
int ans[1005];//病毒i出现的次数
int bianhao[maxn + 5];//当前结束位置的病毒编号
queue q;

void getfail(){
	for(int i = 0; i <= 25; i++){
		if(trie[0][i]){
			fail[trie[0][i]] = 0;
			q.push(trie[0][i]);
		}
	}
	while(!q.empty()){
		int now = q.front(); q.pop();
		for(int i = 0; i <= 25; i++){
			if(trie[now][i]){
				fail[trie[now][i]] = trie[fail[now]][i];
				q.push(trie[now][i]);
			}
			else trie[now][i] = trie[fail[now]][i];
		}
	}
	return;
}

int main(){
	while(~scanf("%d", &n)){
		while(!q.empty()) q.pop();
		tot = 0;
		for(int i = 0; i <= maxn; i++){
			for(int j = 0; j <= 25; j++){
				trie[i][j] = 0;
			}
			fail[i] = 0;
			bianhao[i] = 0;
		}
		for(int i = 1; i <= n; i++){
			scanf(" %s", s[i]); 
			ans[i] = 0;
			int root = 0;
			int len = strlen(s[i]);
			for(int j = 0; j < len; j++){
				if(trie[root][s[i][j] - 'A'] == 0) trie[root][s[i][j] - 'A'] = ++tot;
				root = trie[root][s[i][j] - 'A'];
			}
			bianhao[root] = i;//记录编号
		}
		getfail();
		scanf(" %s", ss);
		int now = 0, len = strlen(ss);
		for(int i = 0; i < len; i++){
			if(ss[i] < 'A' || ss[i] > 'Z') {
				now = 0;
				continue;
			}
			now = trie[now][ss[i] - 'A'];
			for(int j = now; j ; j = fail[j]){
				ans[bianhao[j]]++;
			}
		}
		for(int i = 1; i <= n; i++){
			if(ans[i] != 0){
				printf("%s: ", s[i]);
				printf("%d\n", ans[i]);
			}
		}
	}
	return 0;
}

KeyWord Search(HDU2222)

AC自动机模板+例题(HDU2896+HDU3065+HDU2222)_第3张图片

#include
#include
#include
#include
#include
using namespace std;
const int MaxN = 1e4 *50;

int n;
char s[1000000];
int trie[MaxN + 4][30];
int word[MaxN + 5];
int fail[MaxN + 5];
char ss[1000005];
int tot;

void insert(){
	int root = 0;
	int Len = strlen(s);
	for(int i = 0; i < Len; i++){
		if(trie[root][s[i] - 'a'] == 0){
			trie[root][s[i] - 'a'] = ++tot;
		}
		root = trie[root][s[i] - 'a'];
	}
	word[root]++;
}

void GetNxt(){
	queue q;
	for(int i = 0; i < 26; i++){
		if(trie[0][i]){
			fail[trie[0][i]] = 0;
			q.push(trie[0][i]);
		}
	}
	while(!q.empty()){
		int now = q.front();
		q.pop();
		for(int i = 0; i < 26; i++){
			if(trie[now][i]){
				fail[trie[now][i]] = trie[fail[now]][i];
				q.push(trie[now][i]);
			}
			else trie[now][i] = trie[fail[now]][i];
		}
	}	
}

int Query(){
	int now, ans, Len;
	ans = now = 0;
	Len = strlen(ss);
	for(int i = 0; i < Len; i++){
		now = trie[now][ss[i] - 'a'];
		for(int j = now; j != 0 && word[j] != -1; j = fail[j]){
			ans += word[j];
			word[j] = -1;
		}
	}
	return ans;
}

int main(){
	int t; cin >> t;
	while(t--){
		scanf("%d", &n);
		tot = 0;
		memset(word, 0, sizeof word);
		memset(trie, 0, sizeof trie);
		memset(fail, 0, sizeof fail);
		for(int i = 1; i <= n; i++){
			scanf("%s", s);
			insert();
		}
		fail[0] = 0;
		GetNxt();
		scanf("%s", ss);
		int ans = Query();
		printf("%d\n", ans);
	}
	return 0;
}

hdu2222卡cin cout超时

你可能感兴趣的:(题解,模板)