• luogu P3796【模板】AC自动机(加强版)


    嘟嘟嘟

    这个和某谷的AC自动机模板简单版差不多。

    但还是要注意几点的:

    1.这个是统计出现次数,而不是是否出现,所以在查询的时候加上这个节点的val后,不能把val标记为-1。那么也就可以说查询的时间复杂度能比简单版的稍微第一慢一点。

    2.考虑k个一样的模式串:刚开始我想的是每一个节点开一个vector,记录这里是第几个模式串。但其实没有这个必要,对于相同的模式串,我们只用记录任意一个就行,反而在出现次数上要都加上。因为如果主串中存在这些相同的模式串,那么出现次数应该是出现次数 * k。输出的时候如果是这些串最多,那么都应该把这些输出。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<queue>
     10 #include<assert.h>
     11 #include<ctime>
     12 using namespace std;
     13 #define enter puts("") 
     14 #define space putchar(' ')
     15 #define Mem(a, x) memset(a, x, sizeof(a))
     16 #define In inline
     17 #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
     18 typedef long long ll;
     19 typedef double db;
     20 const int INF = 0x3f3f3f3f;
     21 const db eps = 1e-8;
     22 const int maxs = 1e6 + 5;
     23 const int maxn = 155;
     24 const int maxN = 1.1e4 + 5;
     25 In ll read()
     26 {
     27     ll ans = 0;
     28     char ch = getchar(), las = ' ';
     29     while(!isdigit(ch)) las = ch, ch = getchar();
     30     while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
     31     if(las == '-') ans = -ans;
     32     return ans;
     33 }
     34 In void write(ll x)
     35 {
     36     if(x < 0) x = -x, putchar('-');
     37     if(x >= 10) write(x / 10);
     38     putchar(x % 10 + '0');
     39 }
     40 In void MYFILE()
     41 {
     42 #ifndef mrclr
     43     freopen(".in", "r", stdin);
     44     freopen(".out", "w", stdout);
     45 #endif
     46 }
     47 
     48 int n;
     49 char s[maxs], s2[maxn][100];
     50 
     51 int sum[maxn];
     52 int ch[maxN][26], val[maxN], pos[maxN], f[maxN], cnt = 0;
     53 In int C(char c) {return c - 'a';}
     54 In void Clear(int x) {Mem(ch[x], 0), val[x] = pos[x] = f[x] = 0;}
     55 In void insert(int id, char* s)
     56 {
     57     int len = strlen(s), now = 0;
     58     for(int i = 0; i < len; ++i)
     59     {
     60         int c = C(s[i]);
     61         if(!ch[now][c]) Clear(++cnt), ch[now][c] = cnt;
     62         now = ch[now][c];
     63     }
     64     val[now]++, pos[now] = id;
     65 }
     66 In void build()
     67 {
     68     queue<int> q;
     69     for(int i = 0; i < 26; ++i) if(ch[0][i]) q.push(ch[0][i]);
     70     while(!q.empty())
     71     {
     72         int now = q.front(); q.pop();
     73         for(int i = 0; i < 26; ++i)
     74         {
     75             if(ch[now][i]) f[ch[now][i]] = ch[f[now]][i], q.push(ch[now][i]);
     76             else ch[now][i] = ch[f[now]][i];
     77         }
     78     }
     79 }
     80 In void query(char* s)
     81 {
     82     int len = strlen(s), now = 0;
     83     for(int i = 0; i < len; ++i)
     84     {
     85         int c = C(s[i]);
     86         now = ch[now][c];
     87         for(int j = now; j; j = f[j]) sum[pos[j]] += val[j];
     88     }
     89 }
     90 
     91 In void init()
     92 {
     93     Clear(cnt = 0), Mem(sum, 0);
     94 }
     95 
     96 int main()
     97 {
     98 //    MYFILE();
     99     while(scanf("%d", &n) && n)
    100     {
    101         init();
    102         for(int i = 1; i <= n; ++i)
    103         {
    104             scanf("%s", s2[i]);
    105             insert(i, s2[i]);
    106         }
    107         build();
    108         scanf("%s", s);
    109         query(s);
    110         int Max = -1;
    111         for(int i = 1; i <= n; ++i) Max = max(Max, sum[i]);
    112         write(Max), enter;
    113         for(int i = 1; i <= n; ++i)    if(sum[i] == Max) puts(s2[i]);
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    Android之JSON格式数据解析
    SSH面试题锦集
    Mysql
    (二)Java基础巩固
    (一)Java基础巩固
    (五)Oracle函数 序列 约束 索引
    让css初学者抓狂的属性float
    微信小程序(4)--二维码窗口
    微信小程序(3)--页面跳转和提示框
    微信小程序(2)--下拉刷新和上拉加载更多
  • 原文地址:https://www.cnblogs.com/mrclr/p/9768532.html
Copyright © 2020-2023  润新知