传送门

初学ac自动机。
ac自动机相当于在trie上建立kmp中的ne指针(fail树)

建树的函数build()比较固定;利用bfs+queue的特点还可以同时求出trie的拓扑序。

匹配的时候就可以灵活操作了。。

题意

某人读论文,一篇论文是由许多单词组成的。

但他发现一个单词会在论文中出现很多次,现在他想知道每个单词分别在论文中出现多少次。

输入格式
第一行一个整数 N,表示有多少个单词。

接下来 N 行每行一个单词,单词中只包含小写字母。

输出格式
输出 N 个整数,每个整数占一行,第 i 行的数字表示第 i 个单词在文章中出现了多少次。

数据范围
1≤N≤200,
所有单词长度的总和不超过 106。

输入样例:
3
a
aa
aaa
输出样例:
6
3
1

分析

先建立自动机,发现只需要统计每个单词能被多少个节点跳到就行了。

举例: s=“abcd”; t=“abcdeabcde”
在trie树上:
t[3]会指向s[3](也就是自己,s[3]在trie树上与t[3]是同一个位置,统计为cnt[s[3]]=2)
t[8]会指向s[3](在trie树上与t[3]是同一个位置)
所以,s[3]这个位置的cnt初值为2,又被一个节点指向了->ans=3。
解释的很抽象,,

于是:将所有单词建立trie图之后,利用顺便求出来的拓扑序自底向上更新每个节点的答案值就行了。

代码

#include <bits/stdc++.h>using namespace std;
//-----pre_def----
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<double, double> PDD;
#define fir(i, a, b) for (int i = (a); i <= (b); i++)
#define rif(i, a, b) for (int i = (a); i >= (b); i--)
#define endl '\n'
#define init_h memset(h, -1, sizeof h), idx = 0;
#define lowbit(x) x &(-x)//---------------
const int N = 1e6 + 10;
int n;
int tr[N][26], cnt[N], ne[N], idx;
char str[N];
int id[210];
int q[N];
void init()
{memset(tr, 0, sizeof tr);memset(cnt, 0, sizeof cnt);memset(ne, 0, sizeof ne);idx = 0;
}void insert(int x)
{int root = 0;for (int i = 0; str[i]; i++){int now = str[i] - 'a';if (!tr[root][now])tr[root][now] = ++idx;root = tr[root][now];cnt[root]++;}id[x] = root;
}void ne_build()
{int hh = 0, tt = -1;fir(i, 0, 25) if (tr[0][i]) q[++tt] = tr[0][i];while (hh <= tt){auto t = q[hh++];fir(i, 0, 25){int now = tr[t][i];if (now){ne[now] = tr[ne[t]][i];q[++tt] = now;}else{tr[t][i] = tr[ne[t]][i];}}}
}int main()
{#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);int StartTime = clock();
#endifscanf("%d", &n);fir(i, 1, n){scanf("%s", str);insert(i);}ne_build(); //还可以顺便做topsortrif(i, idx - 1, 0)//queue中一共存过idx个点,编号从0开始 所以是0~idx-1。{cnt[ne[q[i]]] += cnt[q[i]];}fir(i, 1, n) printf("%d\n", cnt[id[i]]);
#ifndef ONLINE_JUDGEprintf("Run_Time = %d ms\n", clock() - StartTime);
#endifreturn 0;
}

P3966 [TJOI2013]单词(AC自动机,Trie图)相关推荐

  1. bzoj 3172: [Tjoi2013]单词 AC自动机

    3172: [Tjoi2013]单词 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  2. BZOJ3172 TJOI2013 单词 AC自动机

    题意:给定N个字符串,设S为N个字符串首尾相连组成的字符串,查询每个字符串在S中出现的次数. 题解: 首先我们在构造Trie的时候,将构造过程中经过的节点的cnt全部++,此时cnt中记录该模式串被多 ...

  3. 洛谷P3966 [TJOI2013]单词(后缀自动机)

    传送门 统计单词出现次数--为啥大家都是写AC自动机的嘞--明明后缀自动机也能做的说-- 统计出现次数这个就直接按长度排序然后做个dp就好,这是SAM的板子的要求啊,不提了 然后考虑怎么让所有串之间隔 ...

  4. luogu_3966【题解】单词 AC自动机

    题面:https://www.luogu.org/problemnew/show/P3966 大意:小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次, ...

  5. 1285. 单词 ac自动机 + fail树

    传送门 文章目录 题意: 思路: 题意: 一篇论文由若干单词构成,且单词间是隔开的,给你nnn个单词,要求你计算每个单词在论文中出现了多少次. 1≤n≤2001\le n\le 2001≤n≤200, ...

  6. P3966 [TJOI2013]单词

    \(\color{#0066ff}{ 题目描述 }\) 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. ...

  7. ac自动机,自动ac机(bushi

    哈哈哈哈我学明白了也许吧.挂几篇题解: b站的这个up讲得太好啦:https://www.bilibili.com/video/BV1uJ411Y7Eg?p=3&vd_source=f5170 ...

  8. AC自动机讲解超详细

    begin:2019/5/2 update 2020/6/12 更新了LaTeX(咕了好久 感谢大家支持! AC自动机详细讲解 AC自动机真是个好东西!之前学KMPKMPKMP被NextNextNex ...

  9. 提高篇 第二部分 字符串算法 第4章 AC自动机

    https://blog.csdn.net/wangyh1008/article/details/81428056 [模板]AC自动机(加强版) 洛谷3796 AC自动机_A_loud_name-CS ...

  10. AC自动机笔记与例题整理

    TP KMP AC自动机建树/图 最后就是例题时间: 搜索关键词 单词 设计密码 修复DNA Codeforces16届黑龙江省赛E题 洛谷:阿狸打字机(经典自动机,fail树上数据结构维护信息) [ ...

最新文章

  1. iPhone中字符串的国际化
  2. 字符串截取,对数字,英文,汉字都可以
  3. java根据经纬度坐标计算两点的距离算法
  4. 渗透操作系统——【靶场实战训练营】快来看看有没有你需要的
  5. Android java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity
  6. python使用rabbitMQ介绍五(话题模式)
  7. Android之jni编译出现no matching function for call to ‘_JNIEnv::GetJava(JNIEnv* , Java VM**)‘解决办法)‘
  8. mysql集群重启报错lock_CentOS7.2 下 MySQL 之 PXC 集群部署【Docker+单机多节点】
  9. java 文件名空格,java关于文件名带有空格的个人见解
  10. python lncrna_lncRNA分析
  11. Groovy的基础语法
  12. asp之ajax技术:responstext中文乱码
  13. thymeleaf中的th:remove用法
  14. 自定义元素探秘及构建可复用组件最佳实践 1
  15. 【心电信号】基于matlab GUI心电信号数字滤波处理【含Matlab源码 1067期】
  16. [软件更新]影拓三代 PTZ系列 系列 驱动程序 V6.1.1-3{链接已修复}
  17. socket pro 启动客户端的命令
  18. 女程序员写代码被骂,把领导萌死,成功治愈“选择困难症”
  19. 计算机有哪些知识,电脑基本操作知识有哪些
  20. [转载] DeepinC . Mr_zkt 集合选数

热门文章

  1. 洛谷P3533 [POI2012]RAN-Rendezvous
  2. java 核型技术 卷2 pdf,NGS-analysis/Structural-Variation.md at master · zhuhuo/NGS-analysis · GitHub...
  3. CS5序列号文件,以后就不用担心序列号了
  4. 跑跑卡丁车rush服务器维护,跑跑卡丁车rush+操作技巧 跑跑卡丁车rush+基础设定
  5. linux安装程序企鹅,在linux下安装fcitx(小企鹅)中文输入法
  6. 计算机软件定时运行,Win7打开定时运行程序的方法
  7. 本地服务启动慢问题及dubbo测试方法记录
  8. Beyong Compare4过期解决办法
  9. Java前端内联和外联的区别,css外联和内联、嵌入的区别是什么?
  10. 早期系统虚拟机分享 windows虚拟机vmdk