您的位置:首页 > 其它

HDU 3065 病毒侵袭持续中 (AC自动机 + hdu有毒)

2016-07-30 09:28 375 查看

原题网址:

http://acm.hdu.edu.cn/showproblem.php?pid=3065

题意:

因为是中文题,我就不翻译成英语了。。。

思路:

ac自动机的模板题。

吐槽:

hdu有毒,明明没说多组样例,但删了while(cin>>)就错了,,,就WA了,,,这不是很尴尬,能不能把中文说清楚。。。

#include <bits/stdc++.h>
#define maxnode 50001
#define sigma 128
using namespace std;
int num[1010];
struct ac_automation{
int ch[maxnode][sigma];
// maxnode 一般设置为 模式串数量*模式串长度
//ch数组里存的都是位置信息,甚至包含了一些失效指针的信息。
int val[maxnode];
//int cnt[maxnode]; // count
int last[maxnode]; // 储存着最后在查询时需要向上层回溯的地址。
int f[maxnode]; // fail指针
int sz;  // the num of the trie
int ans; // answer

void clear(){
sz = 1;
ans = 0;
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
//memset(cnt,0,sizeof(cnt));
}
int idx(char c){
return (int)c;
}

void insert(char s[],int v){
int u = 0;
for(int i = 0; s[i];i++){
int c = idx( s[i] );
if(!ch[u][c]){
memset(ch[sz],0,sizeof(ch[sz]));
ch[u][c] = sz++;
}
u = ch[u][c];
}
//cnt[u]++;
val[u] = v;
}

void build(){
queue<int> q;
f[0] = 0;
for(int i = 0;i < sigma;i++){
if(ch[0][i]){
f[ch[0][i]] = 0;
q.push(ch[0][i]);
last[ch[0][i]] = 0;
}
}

while(!q.empty()){
int now = q.front();
q.pop();
for(int i = 0;i < sigma ;i++){
int son = ch[now][i];
if(!son){
ch[now][i] = ch[f[now]][i];
continue;
}
q.push(son);
f[son] = ch[f[now]][i];
last[son] = val[f[son]] ? f[son] : last[f[son]];
}
}
}

void find(char *s){
int u = 0;
for(int i = 0;s[i];i++){

int c = idx(s[i]);
u = ch[u][c];
if(val[u]){
print(u);
}
else{
print(last[u]);
}
}
}
void print(int u){
if(u){
if(val[u])num[val[u]]++;
//ans += cnt[u];
//cnt[u] = 0;
print(last[u]);
}
}

}ac;

char sub[1001][52];
char text[2000002];

int main(){
int n;
while(cin>>n){
memset(sub,0,sizeof(sub));
memset(num,0,sizeof(num));
ac.clear();

for(int i = 1;i <= n;i++){
scanf("%s",sub[i]);
ac.insert(sub[i],i);
}
ac.build();
scanf("%s",text);
ac.find(text);
for(int i = 1;i <= n;i++){
if(num[i] != 0){
printf("%s: %d\n",sub[i],num[i]);
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: