zoukankan      html  css  js  c++  java
  • 【HNOI2004】L语言

    Description

    给定n个模式串和m个文本串,对于每个文本串,求出这个文本串在模式串中最大匹配长度。

    Solution

    我们采用AC自动机求解。

    首先构建自动机,在Trie上保存模式串,之后通过bfs求出失配数组(AC自动机的模板操作),之后处理匹配操作。

    这里的一个难点就是我们需要记录最大的匹配长度(而不是是否能匹配),因此我们开一个数组记录当前文本串能匹配的最大长度是多少,那么当AC自动机匹配完一个模式串时,如果文本串中这个模式串之前都匹配完成,那么我们在这里标记。跑一边AC自动机,最后倒序扫一遍标记数组,第一个扫描到标记的位置就是最大长度。

    Code

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 int n, m;
     5 char c[21][11], s[1050010];
     6 int ch[100010][27], val[100010], vis[1050010], dep[100010], f[100010], tot;
     7 void insert(char *a) {
     8     int now = 0;
     9     int l = strlen(a);
    10     for (int i = 0; i < l; ++i) {
    11         if (!ch[now][a[i] - 'a']) {
    12             ch[now][a[i] - 'a'] = ++tot;
    13             dep[tot] = dep[now] + 1;
    14         }
    15         now = ch[now][a[i] - 'a'];
    16     }
    17     val[now] = 1;
    18     return ;
    19 }
    20 queue <int> q;
    21 void bfs() {
    22     for (int i = 0; i < 26; ++i) {
    23         if (ch[0][i]) {
    24             f[ch[0][i]] = 0;
    25             q.push(ch[0][i]);
    26         }
    27     }
    28     while (!q.empty()) {
    29         int now = q.front();
    30         q.pop();
    31         for (int i = 0; i < 26; ++i) {
    32             if (ch[now][i]) f[ch[now][i]] = ch[f[now]][i], q.push(ch[now][i]);
    33             else ch[now][i] = ch[f[now]][i];
    34         }
    35     }
    36     return ;
    37 }
    38 int query(char *a) {
    39     vis[0] = 1;
    40     int now = 0, l = strlen(a);
    41     for (int i = 0; i < l; ++i) {
    42         now = ch[now][a[i] - 'a'];
    43         for (int j = now; j; j = f[j]) 
    44             if (val[j] && vis[i + 1 - dep[j]]) {
    45                 vis[i + 1] = 1;
    46                 break ;
    47             }
    48     }
    49     for (int i = l; i; --i)
    50         if (vis[i]) return i;
    51     return 0;
    52 }
    53 int main() {
    54     scanf("%d%d", &n, &m);
    55     for (register int i = 1; i <= n; ++i) {
    56         scanf("%s", c[i]);
    57         insert(c[i]);
    58     }
    59     bfs();
    60     for (register int i = 1; i <= m; ++i) {
    61         memset(vis, 0, sizeof(vis));
    62         scanf("%s", s);
    63         printf("%d
    ", query(s));
    64     }
    65     return 0;
    66 }
    AC Code
  • 相关阅读:
    (二)springmvc+mybatis+dubbo+zookeeper分布式架构 整合
    (一)springmvc+mybatis+dubbo+zookeeper分布式架构 整合
    微服务架构 SpringCloud(四)Ribbon
    微服务架构 SpringCloud(三)注册中心集群篇
    微服务架构 SpringCloud(二)Eureka(服务注册和服务发现基础篇)
    微服务架构 SpringCloud(一)组件和概念介绍
    企业分布式微服务云SpringCloud SpringBoot mybatis (十四)服务注册(consul)
    20 TextView显示阴影
    19 shape
    18 手动发广播扫描sd卡
  • 原文地址:https://www.cnblogs.com/shl-blog/p/11255415.html
Copyright © 2011-2022 走看看