病毒侵袭(HDU-2896)

病毒侵袭(HDU-2896)

HDU - 2896

AC自动机模板题

题目详情:

啊是中文的,那就不解释了

​ 就是关于多个串匹配一个文本串,不过这题的坑真不少!!!

坑:以上字符串中字符都是ASCII码可见字符(不包括回车)。

​ 要用 vis数组来判断,不能直接 word[i]==1
​ 输入中的空格不用理会 估计是数据太弱
​ 要记得排序

这题算是一道模板吧,时间有点仓促,下次好好整理整理
#include <bits/stdc++.h>
#define maxn 110000
using namespace std;

int trie[maxn][130];
int cnt,n,m,ans,total,d;
int word[maxn],fail[maxn];
int s1[maxn];
int tag[maxn],number;
int vis[maxn];

void insert(string s){
	int root = 0;
	for(int i=0;i<s.size();i++){
		int p = s[i];			
		if(!trie[root][p]) trie[root][p] = ++cnt;
		root = trie[root][p];
	}
	word[root]++;
	tag[root] = ++number;
}

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

void query(string s){
	int root = 0;
	for(int i=0;i<s.size();i++){
		root = trie[root][s[i]];
		for(int j=root; j&&vis[j]!=1 ; j=fail[j]){
			ans += word[j];
			if(word[j]>0) s1[d++] = tag[j];
			vis[j] = 1;
		}
	}
}

int main(){
	string s;
	std::ios::sync_with_stdio(false);
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s;
		insert(s);
	}
	getfail();
	cin>>m;
	for(int i=1;i<=m;i++){
		memset(s1,0,sizeof(s1));
		memset(vis,0,sizeof(vis));
		ans = 0;
		d = 0;
		cin>>s;
		query(s);
		if(ans){
			total++;
			printf("web %d:",i);
			sort(s1,s1+d);						//sort
			for(int r=0;r<d;r++){
				printf(" %d",s1[r]);
			}
			printf("\n");
		}
	}
	printf("total: %d\n",total);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值