• [hdu1277]全文检索(AC自动机)


    解题关键:AC自动机模板题,注意字符匹配时若无法匹配,直接用%s即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=12;
     5 const int MAXN=600010;
     6 int num,ans[10020],nn;
     7 bool vis[600010];
     8 bool flag=false;
     9 struct Trie{//数组形式 
    10     int Next[MAXN][N],Fail[MAXN],End[MAXN],root,tot;//大小为所以匹配字符串的总和 
    11     int newnode(){//结构体内部用 
    12         for(int i=0;i<N;i++) Next[tot][i]=-1;
    13         End[tot++]=0;
    14         return tot-1;
    15     }
    16     void init(){
    17         tot=0;
    18         root=newnode();
    19     }
    20     void insert(char buf[],int x){
    21         int len=strlen(buf);
    22         int now=root;//now是temp指针 
    23         for(int i=0;i<len;i++){
    24             int k=buf[i]-'0';
    25             if(Next[now][k]==-1)  Next[now][k]=newnode();//next数组代表的是下一个字符索引 
    26             now=Next[now][k];
    27         }
    28         End[now]=x;//end数组是当前字符串的个数.字典中可能有相同的单词,若只算一次,改为1. 
    29     }
    30     void build(){//构造fail指针,后缀是某些前缀 
    31         queue<int>que;
    32         Fail[root]=root;
    33         for(int i=0;i<N;i++){ 
    34             if(Next[root][i]==-1) Next[root][i]=root;
    35             else{
    36                 Fail[Next[root][i]]=root;
    37                 que.push(Next[root][i]);
    38             }
    39         } 
    40         while(!que.empty()){//bfs,会将所有的匹配子串都遍历到 
    41             int now=que.front();
    42             que.pop();
    43             for(int i=0;i<N;i++){
    44                 if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];
    45                 else{
    46                     Fail[Next[now][i]]=Next[Fail[now]][i];//fail指向最长的 
    47                     que.push(Next[now][i]);
    48                 }
    49             }
    50         }
    51     }
    52     void query(char buf[]){
    53         int len=strlen(buf),now=root;
    54         for(int i=0;i<len;i++){
    55             now=Next[now][buf[i]-'0'];
    56             int temp=now;
    57             while(temp!=root){
    58                 if(End[temp]&&!vis[temp]) ans[nn++]=End[temp],vis[temp]=true,flag=true;
    59                 temp=Fail[temp];
    60             }
    61         }
    62     }
    63 };
    64 
    65 Trie ac;
    66 char buf[60004],buf2[60004],tmp[6002];
    67 int n,m;
    68 int main(){
    69     while(scanf("%d%d",&m,&n)!=EOF){
    70         memset(ans,0,sizeof ans);
    71         memset(vis,0,sizeof vis);
    72         nn=0;
    73         ac.init();
    74         int t=0;
    75         flag=false;
    76         for(int i=1;i<=m;i++){
    77             scanf("%s",tmp);
    78             strcat(buf,tmp);
    79         }
    80            for(int i=1;i<=n;i++){
    81                scanf("%*s %*s %d] %s",&num,buf2);
    82                ac.insert(buf2,num);
    83         }
    84            ac.build();//不要忘记build 
    85         ac.query(buf);
    86         if(flag){
    87             printf("Found key:");
    88             for(int i=0;i<nn;i++){
    89                 printf(" [Key No. %d]",ans[i]);
    90             }
    91             printf("
    ");
    92         }
    93         else printf("No key can be found !
    ");
    94     }
    95     return 0;
    96 } 
  • 相关阅读:
    矩阵树定理 / 生成树计数
    NC20811 蓝魔法师 (树形DP/树上01背包)
    Xor-MST学习/ 2020牛客暑假多校(五)B.Graph
    HDU-6820 Tree (2020杭电多校(五) 1007)
    Flipping Coins (概率DP)
    宝石装箱 容斥+dp
    Rabbit的工作(1) (dP)
    Codeforces-1350 E.Orac and Game of Life
    HDU-6563 Strength (贪心)
    HDU-6558 The Moon (期望DP)
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7507964.html
Copyright © 2020-2023  润新知