zoukankan      html  css  js  c++  java
  • 模板】AC自动机(简单版)

    模板】AC自动机(简单版)

    https://www.luogu.org/problemnew/show/P3808

    这是一道简单的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;

    参考博客:http://www.cnblogs.com/cjyyb/p/7196308.html

    听说有一种需要用trie树做,trie图不能做的题目??先mark下

    关于失配指针的描述:从当前节点开始,沿着其父节点的失配指针不断向上跑,直到到达一个节点,它的儿子中有当前字母,然后把这两个一样的字母连起来。

    首先要构建trie图,然后fail是在trie图上实现的,所以fail上的跳转是在模式串上的跳转,通过这样的跳转,可以快速找到相匹配的模式串 

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define lson l,mid,rt<<1
     4 #define rson mid+1,r,rt<<1|1
     5 #define sqr(x) ((x)*(x))
     6 #define maxn 1000005
     7 typedef long long ll;
     8 typedef unsigned long long ull;
     9 const ull MOD=257;
    10 /*#ifndef ONLINE_JUDGE
    11         freopen("1.txt","r",stdin);
    12 #endif */
    13 
    14 struct tree{
    15     int fail;
    16     int vis[26];
    17     int num;
    18 }ac[1000005];
    19 
    20 int cnt=0;
    21 
    22 void build(string s){///建trie树
    23     int len=s.length();
    24     int now=0;
    25     for(int i=0;i<len;i++){
    26         if(ac[now].vis[s[i]-'a']==0){
    27             ac[now].vis[s[i]-'a']=++cnt;
    28         }
    29         now=ac[now].vis[s[i]-'a'];
    30     }
    31     ac[now].num+=1;
    32 }
    33 
    34 void get_fail(){///构建成trie图
    35     queue<int>Q;
    36     for(int i=0;i<26;i++){
    37         if(ac[0].vis[i]){
    38             ac[ac[0].vis[i]].fail=0;
    39             Q.push(ac[0].vis[i]);
    40         }
    41     }
    42     while(!Q.empty()){
    43         int u=Q.front();
    44         Q.pop();
    45         for(int i=0;i<26;i++){
    46             if(ac[u].vis[i]){
    47                 ac[ac[u].vis[i]].fail=ac[ac[u].fail].vis[i];
    48                 Q.push(ac[u].vis[i]);
    49             }
    50             else{
    51                 ac[u].vis[i]=ac[ac[u].fail].vis[i];///如果当前结点不存在,就指向父亲结点的fail指向的结点的子结点
    52             }
    53         }
    54     }
    55 }
    56 
    57 int ac_query(string s){
    58     int len=s.length();
    59     int now=0,ans=0;
    60     for(int i=0;i<len;i++){
    61         now=ac[now].vis[s[i]-'a'];
    62         for(int t=now;t&&ac[t].num!=-1;t=ac[t].fail){
    63             ans+=ac[t].num;
    64             ac[t].num=-1;
    65         }
    66     }
    67     return ans;
    68 }
    69 
    70 int main(){
    71     #ifndef ONLINE_JUDGE
    72       //  freopen("1.txt","r",stdin);
    73     #endif
    74     //std::ios::sync_with_stdio(false);
    75     string s;
    76     int n;
    77     cin>>n;
    78     for(int i=0;i<n;i++){
    79         cin>>s;
    80         build(s);
    81     }
    82     ac[0].fail=0;
    83     get_fail();
    84     cin>>s;
    85     cout<<ac_query(s)<<endl;
    86 }
    View Code
  • 相关阅读:
    Linux Kernel 2:用户空间的初始化
    Linux Kernel系列一:开篇和Kernel启动概要
    谢宝友:会说话的Linux内核
    如何给USB移动硬盘格式化分区
    AVR单片机最小系统 基本硬件线路与分析
    Altium Designer 基本封装
    AVR单片机命名规则
    LynxFly科研小四轴横空出世,开源,F4,WIFI --(转)
    四轴自适应控制算法的一些尝试开源我的山猫飞控和梯度在线辨识自适应等算法—(转)
    我的四轴专用PID参数整定方法及原理---超长文慎入(转)
  • 原文地址:https://www.cnblogs.com/Fighting-sh/p/10363605.html
Copyright © 2011-2022 走看看