HDU 3065 病毒侵袭持续中

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

病毒侵袭持续中

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7533    Accepted Submission(s): 2626


Problem Description
小t非常感谢大家帮忙解决了他的上一个问题。然而病毒侵袭持续中。在小t的不懈努力下,他发现了网路中的“万恶之源”。这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒很奇怪,这些病毒的特征码很短,而且只包含“英文大写字符”。当然小t好想好想为民除害,但是小t从来不打没有准备的战争。知己知彼,百战不殆,小t首先要做的是知道这个病毒网站特征:包含多少不同的病毒,每种病毒出现了多少次。大家能再帮帮他吗?
 

Input
第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。
接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。
在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。
 

Output
按以下格式每行一个,输出每个病毒出现次数。未出现的病毒不需要输出。
病毒特征码: 出现次数
冒号后有一个空格,按病毒特征码的输入顺序进行输出。
 

Sample Input
     
     
     
     
3 AA BB CC ooxxCC%dAAAoen....END
 

Sample Output
     
     
     
     
AA: 2 CC: 1
Hint
Hit: 题目描述中没有被提及的所有情况都应该进行考虑。比如两个病毒特征码可能有相互包含或者有重叠的特征码段。 计数策略也可一定程度上从Sample中推测。
 

Source
2009 Multi-University Training Contest 16 - Host by NIT
 

Recommend
lcy
 
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>
#include <stack>
#define maxn 50000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657
#define INF 1<<30
const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b)
{
return a>b;
}
struct ACauto
{
int ch[maxn][26];
int sz;
int f[maxn],last[maxn],val[maxn],cnt[maxn];
void init()
{
sz=1;
memset(ch[0],0,sizeof ch[0]);
memset(cnt,0,sizeof cnt);
}
int idx(char c)
{
if(c<='Z'&&c>='A')
return c-'A';
return -1;
}
void add(char *s,int v)
{
int u=0,len=strlen(s);
for(int i=0;i<len;i++)
{
int c=idx(s[i]);
if(!ch[u][c])
{
memset(ch[sz],0,sizeof ch[sz]);
val[sz]=0;
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=v;
}
void getfail()
{
queue<int>q;
f[0]=0;
for(int c=0;c<26;c++)
{
int u=ch[0][c];
if(u)
{
f[u]=0;
q.push(u);
last[u]=0;
}
}
while(!q.empty())
{
int r=q.front();q.pop();
for(int c=0;c<26;c++)
{
int u=ch[r][c];
if(!u)
{
ch[r][c]=ch[f[r]][c];
continue;
}
q.push(u);
f[u]=ch[f[r]][c];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}
void print(int j)
{
if(j)
{
cnt[val[j]]++;
print(last[j]);
}
}
void Find(char *T)
{
int n=strlen(T);
int j=0;
for(int i=0;i<n;i++)
{
int c=idx(T[i]);
if(c<0){j=0;continue;}
while(j&&!ch[j][c])j=f[j];
j=ch[j][c];
if(val[j])print(j);
else if(last[j])print(last[j]);
}
}
}ac;
char t[2000000];
struct node
{
char s[55];
}k[1005];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
//freopen("out.txt","w",stdout);
int n;
while(scanf("%d",&n)!=EOF)
{
ac.init();
for(int i=1;i<=n;i++)
{
scanf("%s",k[i].s);
ac.add(k[i].s,i);
}
getchar();
ac.getfail();
gets(t);
ac.Find(t);
for(int i=1;i<=n;i++)
{
if(ac.cnt[i]>0)
{
printf("%s: %d\n",k[i].s,ac.cnt[i]);
}
}

}
return 0;
}

你可能感兴趣的:(HDU 3065 病毒侵袭持续中)