两道题调好久才调出来,最后发现3065是多组数据,(早知道就看discuss了)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2896
http://acm.hdu.edu.cn/showproblem.php?pid=3065
3065
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
node *net[27];
node *fail;
int cnt,ld;
node ()
{
fail=NULL;
cnt=0;
for (int i=0;i<27;i++)
{
net[i]=NULL;
}
}
}*e[100005],*root;
int ans[1005],tail=1,tou,n,m,cnt,flag[510],len,vis[1005];
char s[2000005],s1[1005][55];
void build_trie(char *S,int id)
{
node *p=root;
int temp;
len=strlen (S);
for(int i = 0; i < len; ++i)
{
temp = s1[id][i]-'A';
if(p->net[temp] == NULL)
p->net[temp] = new node();
p = p->net[temp];
}
p->cnt++;
p->ld=id;
}
void ac_build()
{
int tou=0,tail=1;
e[0]=root;
root->fail=NULL;
while (tou<tail)
{
node *p=e[tou++];
node *temp=NULL;
for(int i=0;i<26;i++)
{
if(p->net[i])
{
if(p==root)
p->net[i]->fail=root;
else
{
node *pre=p->fail;
while(pre)
{
if(pre->net[i])
{
p->net[i]->fail=pre->net[i];
break;
}
pre=pre->fail;
}
if(!pre)
p->net[i]->fail=root;
}
e[tail++]=p->net[i];
}
}
}
}
void query1()
{
int id=0;
memset(ans,0,sizeof(ans));
node *p=root;
int len=strlen(s);
for (int i=0;i<len;i++)
{
if (s[i]>='A'&&s[i]<='Z')
{
id=s[i]-'A';
while(p!=root&&!p->net[id])
p=p->fail;
p=p->net[id];
if(!p)
p=root;
node *tmp=p;
while(tmp!=root&&tmp->cnt>0)
{
ans[tmp->ld]++;
vis[tmp->ld]=1;
tmp=tmp->fail;
}
}else p=root;
}
}
void readdata()
{
while(scanf("%d",&n) == 1)
{
memset(vis,0,sizeof(vis));
root=new node();
for (int i=1;i<=n;i++)
{
scanf("%s",s1[i]);
build_trie(s1[i],i);
}
ac_build();
cnt=0;
int j,r=0;
scanf("%s",s);
query1();
for (j=1;j<=n;j++)
{
if (vis[j]==1)
{
printf("%s: %d",s1[j],ans[j]);
printf("\n");
}
}
}
}
int main()
{
readdata();
}
----------
2896
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
node *net[95];
node *fail;
int cnt;
node ()
{
fail=NULL;
cnt=0;
for (int i=0;i<95;i++)
{
net[i]=NULL;
}
}
}*e[100005],*root;
int ans[1005],tail=1,tou,n,m,cnt,flag[510],len;
char s[10005],s1[505];
void build_trie(char *s,int id)
{
node *p=root;
int temp;
len=strlen (s);
for(int i = 0; i < len; ++i)
{
temp = s[i]-32;
if(p->net[temp] == NULL)
p->net[temp] = new node();
p = p->net[temp];
}
p->cnt=id;
}
void ac_build()
{
int tou=0,tail=1;
e[0]=root;
root->fail=NULL;
while (tou<tail)
{
node *p=e[tou++];
node *temp=NULL;
for(int i=0;i<95;i++)
{
if(p->net[i])
{
if(p==root)
p->net[i]->fail=root;
else
{
node *pre=p->fail;
while(pre)
{
if(pre->net[i])
{
p->net[i]->fail=pre->net[i];
break;
}
pre=pre->fail;
}
if(!pre)
p->net[i]->fail=root;
}
e[tail++]=p->net[i];
}
}
}
}
void query1()
{
memset(ans,0,sizeof(ans));
node *p=root;
int len=strlen(s);
for (int i=0;i<len;i++)
{
int id=s[i]-32;
while(p!=root&&!p->net[id])
p=p->fail;
p=p->net[id];
if(!p)
p=root;
node *tmp=p;
while(tmp!=root)
{
if(tmp->cnt&&!ans[tmp->cnt])
ans[tmp->cnt]=1;
tmp=tmp->fail;
}
}
}
void readdata()
{
while(~scanf("%d",&n))
{
root=new node();
for (int i=1;i<=n;i++)
{
scanf("%s",s1);
build_trie(s1,i);
}
ac_build();
scanf("%d\n",&m);
cnt=0;
for (int i=1;i<=m;i++)
{
int j,r=0;
scanf("%s",s);
query1();
for (j=1;j<=n;j++)
if (ans[j])
{
flag[r++]=j;
}
if (r)
{
printf("web %d:",i);
for(j=0;j<r;j++)
printf(" %d",flag[j]);
printf("\n");
cnt++;
}
}
printf("total: %d\n",cnt);
}
}
int main()
{
readdata();
}