HDOJ-3065 AC自动机..题意大丈夫?

本文介绍如何使用AC自动机处理多组输入案例,包括病毒传播模型的构建及网站源码的遍历方法。通过具体代码实现展示了从读取输入到输出结果的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       坑爹的题意...明明说了第一行怎么怎么..接下来N行怎么怎么...搞半天是多组Case..这不忽悠人么!!

       先用病毒传构造AC自动机..再遍历网站源码...当走到一点,从这点不断fail直到头接点..路径上所有点的经过次数++..


Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#define oo 2000000000
#define ll long long
using namespace std; 
struct node
{
       int son[26],fail,w;
}point[50005];
int n,a[1003],g,had[50005];
char s[2000005],str[1002][52];
queue<int> myqueue;
int main()
{   
       int h,k,len,i,t,ans,num;
       freopen("input.txt","r",stdin);
       freopen("output.txt","w",stdout);
       while (~scanf("%d",&n))
       {
              num=0;
              memset(point,0,sizeof(point));
              memset(a,0,sizeof(a));
              for (t=1;t<=n;t++)
              {
                     scanf("%s",str[t]);
                     len=strlen(str[t]);
                     h=0;
                     for (i=0;i<len;i++)
                     {
                            if (!point[h].son[str[t][i]-'A']) 
                                point[h].son[str[t][i]-'A']=++num;
                            h=point[h].son[str[t][i]-'A']; 
                     }
                     point[h].w=t;
                     a[t]=h;
              }
              while (!myqueue.empty()) myqueue.pop();
              for (i=0;i<26;i++)
                 if (point[0].son[i]) myqueue.push(point[0].son[i]);
              while (!myqueue.empty())
              {
                    h=myqueue.front();
                    myqueue.pop();
                    for (i=0;i<26;i++)
                    {
                           k=point[h].fail;
                           while (k && !point[k].son[i]) k=point[k].fail;
                           point[point[h].son[i]].fail=point[k].son[i];
                           if (!point[h].son[i])
                               point[h].son[i]=point[k].son[i];
                           else
                               myqueue.push(point[h].son[i]);
                    }
              }  
              ans=0;
              memset(had,0,sizeof(had));
              scanf("%s",s); 
              len=strlen(s); 
              h=0;
              for (i=0;i<len;i++)
              {
                    if (s[i]>='A' && s[i]<='Z') 
                       h=point[h].son[s[i]-'A'];
                    else  h=0;
                    k=h;
                    while (k)
                    {
                           had[k]++;
                           k=point[k].fail; 
                    }
              }
              for (t=1;t<=n;t++)
                 if (had[a[t]])
                    printf("%s: %d\n",str[t],had[a[t]]);
       }
       return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值