• AC自动机


    模板题 hdu2222:

      查询主串中出现过几种模式串。

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define REP(i, a, b) for (int i = a; i < b; i++)
     4 #define drep(i, a, b) for (int i = a; i >= b; i--)
     5 #define pb push_back
     6 #define mp make_pair
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 #define travel(x) for (int i = G[x]; i; i = e[i].nx)
     9 #define xx first
    10 #define yy second
    11 
    12 using namespace std;
    13 
    14 typedef long long i64;
    15 typedef pair<int, int> pii;
    16 
    17 const int inf = ~0U >> 1;
    18 const i64 INF = ~0ULL >> 1;
    19 //***************************
    20 
    21 const int maxn = 100005;
    22 
    23 int fail[maxn], ndtot, tab[maxn];
    24 int ch[maxn][128];
    25 char s[10005];
    26 
    27 void add(char *str, int ha) {
    28     int p = 0;
    29     for (int i = 0; str[i]; i++) {
    30         if (!ch[p][str[i] - 32]) ch[p][str[i] - 32] = ++ndtot;
    31         p = ch[p][str[i] - 32];
    32     }
    33     tab[p] = ha;
    34 }
    35 
    36 int que[maxn];
    37 
    38 void build() {
    39     int qh(0), qt(0);
    40     que[++qt] = 0;
    41     while (qh != qt) {
    42         int x = que[++qh];
    43         REP(i, 0, 128) {
    44             if (ch[x][i]) {
    45                 que[++qt] = ch[x][i];
    46                 fail[ch[x][i]] = x ? ch[fail[x]][i] : 0;
    47             }
    48             else ch[x][i] = ch[fail[x]][i];
    49         }
    50     }
    51 }
    52 
    53 bool vis[505];
    54 
    55 int tot = 0, n;
    56 void query(char *str, int haha) {
    57     bool flag = false;
    58     clr(vis);
    59     int p = 0;
    60     for (int i = 0; str[i]; i++) {
    61         p = ch[p][str[i] - 32];
    62         int k = p;
    63         while (k) {
    64             if (tab[k]) vis[tab[k]] = 1, flag = 1;
    65             k = fail[k];
    66         }
    67     }
    68     if (flag) {
    69         printf("web %d:", haha);
    70         rep(i, 1, n) if (vis[i]) printf(" %d", i);
    71         tot++;
    72         puts("");
    73     }
    74 }
    75 
    76 int main() {
    77     scanf("%d", &n);
    78     rep(i, 1, n) { scanf("%s", s); add(s, i); }
    79     build();
    80     int m;
    81     scanf("%d", &m);
    82     tot = 0;
    83     rep(i, 1, m) {
    84         scanf("%s", s);
    85         query(s, i);
    86     }
    87     printf("total: %d
    ", tot);
    88     return 0;
    89 }
    View Code

      

      同类题 hdu2896:

        也是查询主串中出现过几种模式串。

     1 #include <bits/stdc++.h>
     2 #define rep(i, a, b) for (int i = a; i <= b; i++)
     3 #define REP(i, a, b) for (int i = a; i < b; i++)
     4 #define drep(i, a, b) for (int i = a; i >= b; i--)
     5 #define pb push_back
     6 #define mp make_pair
     7 #define clr(x) memset(x, 0, sizeof(x))
     8 #define travel(x) for (int i = G[x]; i; i = e[i].nx)
     9 #define xx first
    10 #define yy second
    11 
    12 using namespace std;
    13 
    14 typedef long long i64;
    15 typedef pair<int, int> pii;
    16 
    17 const int inf = ~0U >> 1;
    18 const i64 INF = ~0ULL >> 1;
    19 //***************************
    20 
    21 const int maxn = 100005;
    22 
    23 int fail[maxn], ndtot, tab[maxn];
    24 int ch[maxn][128];
    25 char s[10005];
    26 
    27 void add(char *str, int ha) {
    28     int p = 0;
    29     for (int i = 0; str[i]; i++) {
    30         if (!ch[p][str[i] - 32]) ch[p][str[i] - 32] = ++ndtot;
    31         p = ch[p][str[i] - 32];
    32     }
    33     tab[p] = ha;
    34 }
    35 
    36 int que[maxn];
    37 
    38 void build() {
    39     int qh(0), qt(0);
    40     que[++qt] = 0;
    41     while (qh != qt) {
    42         int x = que[++qh];
    43         REP(i, 0, 128) {
    44             if (ch[x][i]) {
    45                 que[++qt] = ch[x][i];
    46                 fail[ch[x][i]] = x ? ch[fail[x]][i] : 0;
    47             }
    48             else ch[x][i] = ch[fail[x]][i];
    49         }
    50     }
    51 }
    52 
    53 bool vis[505];
    54 
    55 int tot = 0, n;
    56 void query(char *str, int haha) {
    57     bool flag = false;
    58     clr(vis);
    59     int p = 0;
    60     for (int i = 0; str[i]; i++) {
    61         p = ch[p][str[i] - 32];
    62         int k = p;
    63         while (k) {
    64             if (tab[k]) vis[tab[k]] = 1, flag = 1;
    65             k = fail[k];
    66         }
    67     }
    68     if (flag) {
    69         printf("web %d:", haha);
    70         rep(i, 1, n) if (vis[i]) printf(" %d", i);
    71         tot++;
    72         puts("");
    73     }
    74 }
    75 
    76 int main() {
    77     scanf("%d", &n);
    78     rep(i, 1, n) { scanf("%s", s); add(s, i); }
    79     build();
    80     int m;
    81     scanf("%d", &m);
    82     tot = 0;
    83     rep(i, 1, m) {
    84         scanf("%s", s);
    85         query(s, i);
    86     }
    87     printf("total: %d
    ", tot);
    88     return 0;
    89 }
    View Code

        有一个需要注意的地方,这个题没有多组数据,然后如果写的是数组版,你对存储trie树的数组memset一遍就会mle,可能是如果不memset可以被编译器优化吧。。

  • 相关阅读:
    从首页看CCS布局
    Community Server专题一:概述Community Server
    datagrid程序增加列的方法
    类的关键字
    base 关键字用于从派生类中访问基类的成员:
    关于CS1.1后台管理页面的研究
    如何:创建同步 HTTP 处理程序
    Community Server专题二:体系结构
    SqlTransaction 类
    单继承与多实现
  • 原文地址:https://www.cnblogs.com/y7070/p/4978382.html
Copyright © 2020-2023  润新知