• 洛谷P3808 【模板】AC自动机(简单版)


    题目背景

    这是一道简单的AC自动机模板题。

    用于检测正确性以及算法常数。

    为了防止卡OJ,在保证正确的基础上只有两组数据,请不要恶意提交。

    管理员提示:本题数据内有重复的单词,且重复单词应该计算多次,请各位注意

    题目描述

    给定n个模式串和1个文本串,求有多少个模式串在文本串里出现过。

    输入输出格式

    输入格式:

    第一行一个n,表示模式串个数;

    下面n行每行一个模式串;

    下面一行一个文本串。

    输出格式:

    一个数表示答案

    输入输出样例

    输入样例#1: 
    2
    a
    aa
    aa
    输出样例#1: 
    2

    说明

    subtask1[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6,n=1;

    subtask2[50pts]:∑length(模式串)<=10^6,length(文本串)<=10^6;

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 long long read()
     6 {
     7     long long x=0,f=1;
     8     char ch=getchar();
     9     while(ch>'9'||ch<'0')
    10     {
    11         if(ch=='-')
    12             f=-1;
    13         ch=getchar();
    14     }
    15     while(ch>='0'&&ch<='9')
    16     {
    17         x=x*10+ch-'0';
    18         ch=getchar();
    19     }
    20     return x*f;
    21 }
    22 const int maxn=1e6+10;
    23 char mob[maxn];
    24 int q[maxn];
    25 int n,cnt;
    26 struct node
    27 {
    28     int fail,num;
    29     int ch[30];
    30 } t[maxn];
    31 void insert()
    32 {
    33     int len=strlen(mob),u=0;
    34     for(int i=0; i<len; i++)
    35     {
    36         int s=mob[i]-'a';
    37         if(t[u].ch[s]==0)
    38             t[u].ch[s]=++cnt;
    39         u=t[u].ch[s];
    40     }
    41     t[u].num++;
    42 }
    43 void getfail()
    44 {
    45     int l=0,r=0;
    46     for(int i=0; i<26; i++)
    47         if(t[0].ch[i]!=0)
    48         {
    49             t[t[0].ch[i]].fail=0;
    50             q[++r]=t[0].ch[i];
    51         }
    52     while(l<r)
    53     {
    54         int u=q[++l];
    55         for(int i=0; i<26; i++)
    56         {
    57             int v=t[u].ch[i];
    58             if(v)
    59             {
    60                 t[v].fail=t[t[u].fail].ch[i];
    61                 q[++r]=v;
    62             }
    63             else
    64                 t[u].ch[i]=t[t[u].fail].ch[i];
    65         }
    66     }
    67 }
    68 int query()
    69 {
    70     int len=strlen(mob);
    71     int u=0,ans=0;
    72     for(int i=0; i<len; i++)
    73     {
    74         int s=mob[i]-'a';
    75         u=t[u].ch[s];
    76         int v=u;
    77         while(v&&t[v].num!=-1)
    78         {
    79             ans+=t[v].num;
    80             t[v].num=-1;
    81             v=t[v].fail;
    82         }
    83     }
    84     return ans;
    85 }
    86 int main()
    87 {
    88     n=read();
    89     for(int i=1; i<=n; i++)
    90     {
    91         cin>>mob;
    92         insert();
    93     }
    94     t[0].fail=0;
    95     getfail();
    96     cin>>mob;
    97     printf("%d",query());
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    在线编辑Office文件
    将自然数分解为若干连续的自然数
    C#远程连接Oracle数据库(不安装客户端)
    大数阶乘
    小写金额转换为大写金额
    SQL优化
    C#枚举器:foreach语句、IEnumerable、IEnumerator以及yield return (二)
    C#枚举器:foreach语句、IEnumerable、IEnumerator以及yield return (一)
    PPT播完最后一个动画后自动进入下一页
    C#中的abstract、virtual、override和new
  • 原文地址:https://www.cnblogs.com/liweilin/p/10198643.html
Copyright © 2020-2023  润新知