zoukankan      html  css  js  c++  java
  • [hdu3065]病毒侵袭持续中(AC自动机)

    题意:给出多种病毒的号码和特征码,计算在某串中各病毒匹配的次数。

    解题关键:AC自动机模板题,多组输入坑人。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=96;
     5 const int MAXN=50010;
     6 int num,ans[1002],nn;
     7 char vir[1002][52];
     8 struct Trie{//数组形式 
     9     int Next[MAXN][N],Fail[MAXN],End[MAXN],root,tot;//大小为所以匹配字符串的总和 
    10     int newnode(){//结构体内部用 
    11         for(int i=0;i<N;i++) Next[tot][i]=-1;
    12         End[tot++]=0;
    13         return tot-1;
    14     }
    15     void init(){
    16         tot=0;
    17         root=newnode();
    18     }
    19     void insert(char buf[],int x){
    20         int len=strlen(buf);
    21         int now=root;//now是temp指针 
    22         for(int i=0;i<len;i++){
    23             int k=buf[i]-32;
    24             if(Next[now][k]==-1)  Next[now][k]=newnode();//next数组代表的是下一个字符索引 
    25             now=Next[now][k];
    26         }
    27         End[now]=x;//end数组是当前字符串的个数.字典中可能有相同的单词,若只算一次,改为1. 
    28     }
    29     void build(){//构造fail指针,后缀是某些前缀 
    30         queue<int>que;
    31         Fail[root]=root;
    32         for(int i=0;i<N;i++){ 
    33             if(Next[root][i]==-1) Next[root][i]=root;
    34             else{
    35                 Fail[Next[root][i]]=root;
    36                 que.push(Next[root][i]);
    37             }
    38         } 
    39         while(!que.empty()){//bfs,会将所有的匹配子串都遍历到 
    40             int now=que.front();
    41             que.pop();
    42             for(int i=0;i<N;i++){
    43                 if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];
    44                 else{
    45                     Fail[Next[now][i]]=Next[Fail[now]][i];//fail指向最长的 
    46                     que.push(Next[now][i]);
    47                 }
    48             }
    49         }
    50     }
    51     void query(char buf[]){
    52         int len=strlen(buf),now=root;
    53         for(int i=0;i<len;i++){
    54             now=Next[now][buf[i]-32];
    55             int temp=now;
    56             while(temp!=root){
    57                 if(End[temp]) ans[End[temp]]++;
    58                 temp=Fail[temp];
    59             }
    60         }
    61     }
    62 };
    63 
    64 Trie ac;
    65 char buf[2000004];
    66 int n,m;
    67 int main(){
    68     while(scanf("%d",&n)!=EOF){
    69         memset(ans,0,sizeof ans);
    70         ac.init();
    71         for(int i=1;i<=n;i++){
    72             scanf("%s",vir+i);
    73             ac.insert(vir[i],i);
    74         }
    75            ac.build();//不要忘记build 
    76            scanf("%s",buf);
    77         ac.query(buf);
    78         for(int i=1;i<=n;i++){
    79             if(!ans[i]) continue;
    80             printf("%s: %d
    ",vir[i],ans[i]);
    81         }
    82     }
    83 
    84     return 0;
    85 } 
  • 相关阅读:
    vscode Git提交
    安装 nrm
    vue+element ui项目总结点(六)table编辑当前行、删除当前行、新增、合计操作
    Filebrowser安装教程
    vue数据处理:把数组处理成适用于tree组件的数据
    WC2016模拟Divisor
    对拍模板
    题解(5031. 【NOI2017模拟3.27】B)(数论,组合数学)
    Codeforces #657 Div2C choosing flowers
    关于一个大菜鸡的记录
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7507326.html
Copyright © 2011-2022 走看看