题目大意:有$n$个字符串,求每个字符串在所有字符串中出现的次数

题解:$AC$自动机,每个节点被经过时$sz$加一,每一个字符串出现次数为其$fail$树子树$sz$和

卡点:$AC$自动机根节点为$1$,没有在$build$的时候将所有空的$nxt[1][i]$赋值为$1$

C++ Code:

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <queue>
  5. const int maxn = 1e6 + 10;
  6.  
  7. std::string s;
  8. int n, ret[210];
  9. namespace AC {
  10. int nxt[maxn][26], fail[maxn], idx = 1, cnt[maxn];
  11. int insert(std::string s) {
  12. int p = 1;
  13. for (char ch : s) {
  14. if (nxt[p][ch - 'a']) p = nxt[p][ch - 'a'];
  15. else p = nxt[p][ch - 'a'] = ++idx;
  16. ++cnt[p];
  17. }
  18. return p;
  19. }
  20. void build() {
  21. static std::queue<int> q;
  22. for (int i = 0; i < 26; ++i)
  23. if (nxt[1][i]) fail[nxt[1][i]] = 1, q.push(nxt[1][i]);
  24. else nxt[1][i] = 1;
  25. while (!q.empty()) {
  26. int u = q.front(); q.pop();
  27. for (int i = 0; i < 26; ++i)
  28. if (nxt[u][i]) fail[nxt[u][i]] = nxt[fail[u]][i], q.push(nxt[u][i]);
  29. else nxt[u][i] = nxt[fail[u]][i];
  30. }
  31. }
  32.  
  33. int head[maxn], CNT;
  34. struct Edge {
  35. int to, nxt;
  36. } e[maxn];
  37. void addedge(int a, int b) {
  38. e[++CNT] = (Edge) { b, head[a] }; head[a] = CNT;
  39. }
  40. void dfs(int u) {
  41. for (int i = head[u], v; i; i = e[i].nxt) {
  42. v = e[i].to;
  43. dfs(v);
  44. cnt[u] += cnt[v];
  45. }
  46. }
  47. void solve() {
  48. for (int i = 2; i <= idx; ++i) addedge(fail[i], i);
  49. dfs(1);
  50. }
  51. }
  52. int main() {
  53. std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
  54. std::cin >> n;
  55. for (int i = 0; i < n; ++i) {
  56. std::cin >> s;
  57. ret[i] = AC::insert(s);
  58. }
  59. AC::build(), AC::solve();
  60. for (int i = 0; i < n; ++i) std::cout << AC::cnt[ret[i]] << '\n';
  61. return 0;
  62. }

  

[洛谷P3966][TJOI2013]单词的更多相关文章

  1. 洛谷P3966 [TJOI2013]单词(fail树性质)

    P3966 [TJOI2013]单词 题目链接:https://www.luogu.org/problemnew/show/P3966 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单 ...

  2. 洛谷P3966 [TJOI2013]单词(AC自动机)

    题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出格式 输入格式: 第一行一个整数N,表 ...

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

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

  4. BZOJ3172 & 洛谷3966 [Tjoi2013]单词 【fail树】

    3172: [Tjoi2013]单词 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 4293  Solved: 2083 [Submit][Stat ...

  5. P3966 [TJOI2013]单词

    P3966 [TJOI2013]单词 题目描述 小张最近在忙毕设,所以一直在读论文.一篇论文是由许多单词组成但小张发现一个单词会在论文中出现很多次,他想知道每个单词分别在论文中出现了多少次. 输入输出 ...

  6. 【洛谷 P3966】 [TJOI2013]单词(AC自动机,差分)

    把单词连起来,中间插入间隔符,同 #include <cstdio> #include <queue> #include <cstring> using names ...

  7. 洛谷P3966 单词 [TJOI2013] AC自动机

    正解:AC自动机 解题报告: 传送门! 先来提供一个40pts错解QAQ 首先看到这题就会想到AC自动机板子题2鸭!然后就照着那题的套路打一下,随便改一点儿,简单来说就是每次经过一个节点都要++,然后 ...

  8. 洛谷 - P3966 - 单词 - AC自动机

    https://www.luogu.org/problemnew/show/P3966 因为文本串就是字典本身,所以这个和平时的AC自动机不太一样.平时的query要沿着fail树把子树的出现次数依次 ...

  9. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

随机推荐

  1. vue-cli之路由独立成JS文件之后,如何在路由中获取vuex属性或者设置国际化i18n的当前使用语言

    国际化vue-i18n的使用: import Vue from 'vue'; import VueI18n from 'vue-i18n'; // 引入语言包 import zh from '@/co ...

  2. mysql 创建联结

    mysql> select * from user; +------+----------+-----------+ | id | name | address | +------+------ ...

  3. PHP 之Mysql优化

    一.建立索引 普通索引 index: 对关键字没有要求. 唯一索引 unique index: 要求关键字不能重复.同时增加唯一约束. 主键索引 primary key: 要求关键字不能重复,也不能为 ...

  4. 怎么样使element ui 的table某列变色

    第一步.在el-table里面加上:row-style="rowClass" <el-table :data="targetCarList" border ...

  5. Linux 文件压缩、打包

    文件压缩 计算机使用byte单位来计量.实际上,计算机最小的计量单位是bit.1byte = 8 bit.如果记录1这个数字,00000001,1会在最右边占一个1个bit 其他7个bit会被填上0. ...

  6. layui如何自定义弹出层关闭事件

    在某些业务场景下,我们需要自定义弹出层关闭事件,代码示例如下: layui.use('layer', function () { var layer = layui.layer; layer.open ...

  7. 子查询优化 - Hyper

    Unnesting Arbitrary Queries - T Neumann, A KemperThe Complete Story of Joins (in HyPer) - Thomas Neu ...

  8. SpringBoot过滤XSS脚本攻击

    XSS攻击是什么 XSS攻击全称跨站脚本攻击,是为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS,XSS是一种在web应用中的计算机安 ...

  9. ARM USB 通信(转)

    ARM USB 通信 采用ZLG的动态链接库,动态装载. ARM是Context-M3-1343. 在C++ Builder 6 中开发的上位机通信软件. USB通信代码如下: //--------- ...

  10. 【winform】主窗体多线程给子窗体传值

    1.主窗体多线程给子窗体传值 解决方案:主要使用委托,因为会出现跨线程错误 主窗体 public FormMain() { InitializeComponent(); //background th ...