zoukankan      html  css  js  c++  java
  • [洛谷3796]【模板】AC自动机(加强版)

    题目大意:
      给定$n(nleq150)$个模式串$p_i(|p_i|le70)$和一个$t(|t|le10^6)$,求$t$中被匹配次数最多的$p_i$。

    思路:
      AC自动机。匹配时记录一下匹配次数即可。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<algorithm>
     5 inline int getint() {
     6     register char ch;
     7     while(!isdigit(ch=getchar()));
     8     register int x=ch^'0';
     9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    10     return x;
    11 }
    12 const int N=150,L1=71,L2=1e6+1,S=26;
    13 int cnt[N];
    14 char s[N][L1],t[L2];
    15 class AhoCorasick {
    16     private:
    17         std::queue<int> q;
    18         int val[N*L1]={-1},ch[N*L1][S],fail[N*L1];
    19         int sz,new_node() {
    20             fail[++sz]=0;
    21             val[sz]=-1;
    22             std::fill(&ch[sz][0],&ch[sz][S],0);
    23             return sz;
    24         }
    25         int idx(const int &c) const {
    26             return c-'a';
    27         }
    28     public:
    29         void reset() {
    30             std::fill(&ch[0][0],&ch[0][S],sz=0);
    31         }
    32         void insert(const char s[],const int &id) {
    33             int p=0;
    34             for(register int i=0;s[i];i++) {
    35                 const int c=idx(s[i]);
    36                 p=ch[p][c]?:ch[p][c]=new_node();
    37             }
    38             val[p]=id;
    39         }
    40         void get_fail() {
    41             for(register int i=0;i<S;i++) {
    42                 if(ch[0][i]) q.push(ch[0][i]);
    43             }
    44             while(!q.empty()) {
    45                 const int &x=q.front();
    46                 for(register int i=0;i<S;i++) {
    47                     int &y=ch[x][i];
    48                     if(!y) {
    49                         y=ch[fail[x]][i];
    50                         continue;
    51                     }
    52                     fail[y]=ch[fail[x]][i];
    53                     q.push(y);
    54                 }
    55                 q.pop();
    56             }
    57         }
    58         void find(const char s[]) {
    59             for(register int i=0,p=0;s[i];i++) {
    60                 for(register int j=p=ch[p][idx(s[i])];j;j=fail[j]) {
    61                     if(~val[j]) cnt[val[j]]++;
    62                 }
    63             }
    64         }
    65 };
    66 AhoCorasick ac;
    67 int main() {
    68     for(int n;(n=getint());) {
    69         ac.reset();
    70         for(register int i=0;i<n;i++) {
    71             cnt[i]=0;
    72             scanf("%s",s[i]);
    73             ac.insert(s[i],i);
    74         }
    75         ac.get_fail();
    76         scanf("%s",t);
    77         ac.find(t);
    78         int ans=0;
    79         for(register int i=0;i<n;i++) ans=std::max(ans,cnt[i]);
    80         printf("%d
    ",ans);
    81         for(register int i=0;i<n;i++) {
    82             if(cnt[i]==ans) puts(s[i]);
    83         }
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Redis详解----- 缓存穿透、缓存击穿、缓存雪崩
    mysql存储时间
    MAT入门到精通
    meven依赖思考记录
    线程池原理
    vscode + wsl2
    java架构师学习路线-高级
    java架构师学习路线-初级
    (二)垃圾回收
    (一)内存区域
  • 原文地址:https://www.cnblogs.com/skylee03/p/8570001.html
Copyright © 2011-2022 走看看