2434: [Noi2011]阿狸的打字机

https://lydsy.com/JudgeOnline/problem.php?id=2434

分析:

  AC自动机。

  查询x在y中出现了几次,就是查询y在AC自动机上有多少节点的可以通过fail指针指向x,反过来就是查询fail树上,x的子树内有多少y的点。

  fail树的性质:父节点是子节点的最长的后缀。

  然后dfs序+树状数组可以求,把子串y标记了,在x所对应的区间查询即可。阿狸的打字机有一个性质,可以在扫一遍字符串的过程得到所有的字符串,所以扫一遍的过程,维护的加入删除操作,一旦出现了一个“P”,那么前面加入的所有点就是这个串的字符。

代码:

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<cmath>
  6 #include<cctype>
  7 #include<set>
  8 #include<queue>
  9 #include<vector>
 10 #include<map>
 11 #define pa pair<int,int>
 12 #define mp make_pair
 13 using namespace std;
 14 typedef long long LL;
 15
 16 inline int read() {
 17     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
 18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
 19 }
 20
 21 const int N = 200005;
 22
 23 char s[N];
 24 vector<int> T[N];
 25 int ch[N][27], q[N], fail[N], last[N], pos[N], L[N], R[N], ans[N];
 26 int cnt, Index, Time_Index;
 27 struct BIT{
 28     int n, sum[N];
 29     void update(int p,int v) {
 30         for (; p <= n; p += (p & (-p))) sum[p] += v;
 31     }
 32     int query(int p) {
 33         int ans = 0;
 34         for (; p; p -= (p & (-p))) ans += sum[p];
 35         return ans;
 36     }
 37     int Ask(int l,int r) {
 38         return query(r) - query(l - 1);
 39     }
 40 }bit;
 41 vector< pa > Que[N];
 42
 43 void Insert(char *s,int n) {
 44     int u = 0;
 45     for (int i = 0; i < n; ++i) {
 46         if (s[i] >= 'a' && s[i] <= 'z') {
 47             int c = s[i] - 'a';
 48             if (!ch[u][c]) ch[u][c] = ++Index;
 49             last[ch[u][c]] = u, u = ch[u][c];
 50         }
 51         else if (s[i] == 'B') u = last[u];
 52         else pos[++cnt] = u;
 53     }
 54 }
 55 void bfs() {
 56     int L = 1, R = 0;
 57     for (int c = 0; c < 26; ++c) if (ch[0][c]) q[++R] = ch[0][c];
 58     while (L <= R) {
 59         int u = q[L ++];
 60         T[fail[u]].push_back(u);
 61         for (int c = 0; c < 26; ++c) {
 62             int v = ch[u][c];
 63             if (!v) { ch[u][c] = ch[fail[u]][c]; continue; }
 64             int p = fail[u]; while (p && !ch[p][c]) p = fail[p];
 65             fail[v] = ch[p][c];
 66             q[++R] = v;
 67         }
 68     }
 69 }
 70 void dfs(int u) {
 71     L[u] = ++Time_Index;
 72     for (int sz = T[u].size(), i = 0; i < sz; ++i) dfs(T[u][i]);
 73     R[u] = Time_Index;
 74 }
 75 int main() {
 76     scanf("%s", s);
 77     int n = strlen(s);
 78     Insert(s, n);
 79     bfs();
 80     dfs(0); bit.n = Time_Index; // not Index || Index + 1
 81     int m = read();
 82     for (int i = 1; i <= m; ++i) {
 83         int x = read(), y = read();
 84         Que[y].push_back(mp(x, i));
 85     }
 86     int now = 0, cnt = 0;
 87     for (int i = 0; i < n; ++i) {
 88         if(s[i] >= 'a' && s[i] <= 'z')
 89             now = ch[now][s[i] - 'a'], bit.update(L[now], 1);
 90         else if (s[i] == 'B')
 91             bit.update(L[now], -1), now = last[now];
 92         else {
 93             cnt ++;
 94             for (int sz = Que[cnt].size(), j = 0; j < sz; ++j) {
 95                 int id = Que[cnt][j].second, x = Que[cnt][j].first;
 96                 ans[id] = bit.Ask(L[pos[x]], R[pos[x]]);
 97             }
 98         }
 99     }
100     for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
101     return 0;
102 }

转载于:https://www.cnblogs.com/mjtcn/p/10092980.html

2434: [Noi2011]阿狸的打字机相关推荐

  1. [bzoj 2434][Noi2011]阿狸的打字机

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory ...

  2. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2545  Solved: 1419 [Submit][S ...

  3. bzoj 2434 [Noi2011]阿狸的打字机(AC自动机+fail树+dfs序+树状数组)

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 3521  Solved: 1913 [Submit][S ...

  4. BZOJ 2434: [Noi2011]阿狸的打字机 ACAM+fail树

    title BZOJ 2434 LUOGU 2414 Description 打字机上只有 \(28\) 个按键,分别印有 \(26\) 个小写英文字母和 B.P 两个字母,是这样工作的: 输入小写字 ...

  5. [BZOJ 2434][Noi2011]阿狸的打字机(AC自动机+树状数组+dfs序)

    Description 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母.经阿狸研究发现,这个打字机是这样工作的: ·输入小写字母,打字机的一个凹槽中会加入这个字母(这个字母 ...

  6. BZOJ 2434 NOI2011阿狸的打字机 AC自动机+树状数组

    如果你还没学AC自动机,请看这篇博客 Problem bzoj通道 洛谷通道 Solution 简单的说来,其实就是要快速求一个字符串在另一个字符串中出现了多少次.考虑构造AC自动机. 首先可以想到很 ...

  7. bzoj 2434: [Noi2011]阿狸的打字机

    题意: 给出一个字典树,并告诉你若干串的结束位置.求第x个串在第y个串的出现次数. 题解: 不难的AC自动机+不难的主席树. 首先对于字典树建AC自动机,那么对于一个串S,假如能在这个串的结尾点不断跳 ...

  8. 【bzoj 2434】【codevs 1946】[Noi2011]阿狸的打字机(AC自动机)

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MB Submit: 2477  Solved: 1382 [Submit][S ...

  9. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

最新文章

  1. 论supervisor的使用(一)
  2. linux更新驱动脚本,编写Linux驱动常见错误(不断更新)!
  3. 一定是h的方式不对阅读_20T/H中水 超滤回用处理系统
  4. python路3--tuple、str
  5. java例程练习(一维数组)
  6. 关于java assertion
  7. python运维开发笔记5
  8. codeforces 361 D. Levko and Array(dp+二分)
  9. Mybatis缓存模块(一)BlockingCache
  10. 获取一个APK的版本号
  11. firefox 模拟手机
  12. h5页面如何切图_html5怎么切图
  13. 分解gif动图如何操作?手把手教你动图分解方法
  14. Python while循环及用法详解
  15. Siebel 数学运算
  16. 基于xsh的vbs脚本的使用(简介)
  17. 聚类时的轮廓系数评价和inertia_
  18. windows和linux环境下的嵌入式开发区别
  19. python开发工程师岗位简介_python开发工程师是什么
  20. 拼多多商品发布规则|一度智信

热门文章

  1. js中的preventDefault
  2. 用饮水机教你什么是RAID [转]
  3. 特殊方法,类之间的关系,分页
  4. vue-cli 中使用 less 插件
  5. 从 TensorFlow 入门机器学习
  6. DataGridView 用户输入时,单元格输入值的设定
  7. swift:创建表格UITableView
  8. 大数据热门职业薪酬榜 Hadoop人才居首
  9. 戴尔发布面向制造、生命科学和研究的高性能计算系统
  10. 在项目中使用 calendar_date_select