AC自动机模板3【洛谷3796】
AC自动机的第三个模板
其实,个人觉得,目前我写的这三个不同的模板完全是可以合并在一起求解的。
只是,在这两个无关联的OJ上,同一个AC自动机都可以完成的问题被拆成了三道题而已。
因此,代码只需要略加修改即可解决这道题。
具体题目请上洛谷查看
https://www.luogu.org/problem/show?pid=3796
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;
struct Tree//字典树
{
     int fail;//失配指针
     int vis[26];//子节点的位置
     int end;//标记以这个节点结尾的单词编号
}AC[100000];//Trie树
int cnt=0;//Trie的指针
struct Result
{
      int num;
      int pos;
}Ans[100000];//所有单词的出现次数
bool operator <(Result a,Result b)
{
      if(a.num!=b.num)
         return a.num>b.num;
      else
         return a.pos<b.pos;
}
string s[100000];
inline void Clean(int x)
{
       memset(AC[x].vis,0,sizeof(AC[x].vis));
       AC[x].fail=0;
       AC[x].end=0;
}
inline void Build(string s,int Num)
{
        int l=s.length();
        int now=0;//字典树的当前指针
        for(int i=0;i<l;++i)//构造Trie树
        {
                if(AC[now].vis[s[i]-'a']==0)//Trie树没有这个子节点
                {
                   AC[now].vis[s[i]-'a']=++cnt;//构造出来
                   Clean(cnt);
                }
                now=AC[now].vis[s[i]-'a'];//向下构造
        }
        AC[now].end=Num;//标记单词结尾
}
void Get_fail()//构造fail指针
{
        queue<int> Q;//队列
        for(int i=0;i<26;++i)//第二层的fail指针提前处理一下
        {
               if(AC[0].vis[i]!=0)
               {
                   AC[AC[0].vis[i]].fail=0;//指向根节点
                   Q.push(AC[0].vis[i]);//压入队列
               }
        }
        while(!Q.empty())//BFS求fail指针
        {
              int u=Q.front();
              Q.pop();
              for(int i=0;i<26;++i)//枚举所有子节点
              {
                        if(AC[u].vis[i]!=0)//存在这个子节点
                      {
                                AC[AC[u].vis[i]].fail=AC[AC[u].fail].vis[i];
                                    //子节点的fail指针指向当前节点的
                                  //fail指针所指向的节点的相同子节点
                                Q.push(AC[u].vis[i]);//压入队列
                      }
                      else//不存在这个子节点
                      AC[u].vis[i]=AC[AC[u].fail].vis[i];
                      //当前节点的这个子节点指向当
                      //前节点fail指针的这个子节点
              }
        }
}
int AC_Query(string s)//AC自动机匹配
{
        int l=s.length();
        int now=0,ans=0;
        for(int i=0;i<l;++i)
        {
                now=AC[now].vis[s[i]-'a'];//向下一层
                for(int t=now;t;t=AC[t].fail)//循环求解
                         Ans[AC[t].end].num++;
        }
        return ans;
}
int main()
{
     int n;
     while(233)
     {
          cin>>n;
          if(n==0)break;
          cnt=0;
          Clean(0);
         for(int i=1;i<=n;++i)
         {
                 cin>>s[i];
                 Ans[i].num=0;
                 Ans[i].pos=i;
                 Build(s[i],i);
         }
         AC[0].fail=0;//结束标志
         Get_fail();//求出失配指针
         cin>>s[0];//文本串
         AC_Query(s[0]);
         sort(&Ans[1],&Ans[n+1]);
         cout<<Ans[1].num<<endl;
         cout<<s[Ans[1].pos]<<endl;
         for(int i=2;i<=n;++i)
         {
                if(Ans[i].num==Ans[i-1].num)
                  cout<<s[Ans[i].pos]<<endl;
                else
                   break;
         }
     }
     return 0;
}
												
											AC自动机模板3【洛谷3796】的更多相关文章
- UVALive-4670 Dominating Patterns  / 洛谷 3796 【模板】AC自动机
		
https://vjudge.net/problem/UVALive-4670 中文题面:https://www.luogu.org/problem/show?pid=3796 AC自动机模板 注意如 ...
 - HDU 2222 AC自动机模板题
		
题目: http://acm.hdu.edu.cn/showproblem.php?pid=2222 AC自动机模板题 我现在对AC自动机的理解还一般,就贴一下我参考学习的两篇博客的链接: http: ...
 - Match:Keywords Search(AC自动机模板)(HDU 2222)
		
多模匹配 题目大意:给定很多个字串A,B,C,D,E....,然后再给你目标串str字串,看目标串中出现多少个给定的字串. 经典AC自动机模板题,不多说. #include <iostream& ...
 - HDU 3065 (AC自动机模板题)
		
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 题目大意:多个模式串,范围是大写字母.匹配串的字符范围是(0~127).问匹配串中含有哪几种模 ...
 - HDU 2896 (AC自动机模板题)
		
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2896 题目大意:多个模式串.多个匹配串.其中串的字符范围是(0~127).问匹配串中含有哪几个模式串 ...
 - HDU 2222(AC自动机模板题)
		
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2222 题目大意:多个模式串.问匹配串中含有多少个模式串.注意模式串有重复,所以要累计重复结果. 解题 ...
 - HDU 2222 (AC自动机模板题)
		
题意: 给一个文本串和多个模式串,求文本串中一共出现多少次模式串 分析: ac自动机模板,关键是失配函数 #include <map> #include <set> #incl ...
 - hdu 2222 Keywords Search    ac自动机模板
		
题目链接 先整理一发ac自动机模板.. #include <iostream> #include <vector> #include <cstdio> #inclu ...
 - 点分治模板(洛谷P4178 Tree)(树分治,树的重心,容斥原理)
		
推荐YCB的总结 推荐你谷ysn等巨佬的详细题解 大致流程-- dfs求出当前树的重心 对当前树内经过重心的路径统计答案(一条路径由两条由重心到其它点的子路径合并而成) 容斥减去不合法情况(两条子路径 ...
 - KMP与AC自动机模板
		
HDU 1711 Number Sequence(KMP模板题) http://acm.hdu.edu.cn/showproblem.php?pid=1711 #include<bits/std ...
 
随机推荐
- 使用Nginx实现灰度发布
			
灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B ...
 - cassandra 鉴权
			
1. 修改cassandra.yaml配置文件.启用用户密码登录形式. authenticator: PasswordAuthenticator authorizer: CassandraAuthor ...
 - hihoCoder 树结构判定(并查集)
			
思路:树满足两个条件: 1.顶点数等于边数加一 2.所有的顶点在一个联通块 那么直接dfs或者并查集就可以了. AC代码 #include <stdio.h> #include<st ...
 - nyoj234 吃土豆 01背包
			
思路:假设我们先只考虑一行,规则就是取了i处的土豆,每一个土豆有两种选择,拿与不拿,那么i-1和i+1处的土豆都不能再取,那么要求某一行的最大取值就用一次动态规划即可,dp(i)表示前i个土豆能取得的 ...
 - 理解 Git
			
Git 如何保存文件 其它版本管理系统通常会保存所有文件及其历次提交的差异(diff / revision),通过 merge 原始文件与各阶段的差异就能获取任何版本的状态 而 Git 保存的是每一次 ...
 - JAVA 处理 Spring data mongodb 时区问题
			
Spring data mongodb 查询出结果的时候会自动 + 8小时,所以我们看起来结果是对的 但是我们查询的时候,并不会自动 + 8小时,需要自己处理 解决方法 1 @JsonFormat ...
 - MYSQL,触发器,实现两个表共用ID不重复
			
前后台没有分开,为了区分前后台用户,所以分表,但是ID不能重复,因为关联了权限表. 这里实现后台用户表使用奇数ID 前台用户表使用偶数ID MYSQL 没有sequence SET @@auto_in ...
 - Ironic几种不同的场景下的网络拓扑
			
最近帮领导做了几页ppt,总结几种场景下ironic管理物理机网络的网络拓扑,简单做成一份文章记录下.只是方便自己记忆,没有认真修改.如果对ironic有一定了解,可以看下,加深理解. 1. vlan ...
 - DTCMS插件的制作实例电子资源管理(四)URL重写
			
总目录 插件目录结构(一) Admin后台页面编写(二) 前台模板页编写(三) URL重写(四) 本实例旨在以一个实际的项目中的例子来介绍如何在dtcms中制作插件,本系列文章非入门教程,部分逻辑实现 ...
 - js将汉字转为相应的拼音
			
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...