可以非常轻易的将题意转化为有多少子串满足排名相同

注意到$KMP$算法只会在当前字符串的某尾添加和删除字符

因此,如果添加和删除后面的字符对于前面的字符没有影响时,我们可以用$KMP$来模糊匹配

对于本题而言,在末尾插入一个字符时,如果$S$串和$T$串中这两个字符的排名一样,那么它们对前面的影响也是一样的

因此,插入或者删除字符时,后面的字符如果排名一样,可以任何对前面没有影响

反之,如果不一样,那么无法匹配

所以,这满足模糊匹配的条件

我们可以拿树状数组来维护插入和删除

由于$next[i] \leq next[i - 1] + 1$,因此分析一下复杂度不会超过$O(n \log n)$

好像带了大常数......

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. namespace remoon {
  6. #define ri register int
  7. #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
  8. #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)
  9. #define gc getchar
  10. inline int read() {
  11. int p = , w = ; char c = gc();
  12. while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
  13. while(c >= '' && c <= '') p = p * + c - '', c = gc();
  14. return p * w;
  15. }
  16. }
  17. using namespace std;
  18. using namespace remoon;
  19.  
  20. const int sid = ;
  21.  
  22. int n, m, cm, tot;
  23. int ans[sid], nxt[sid], pre[sid];
  24. int t[sid], p[sid], h[sid], T[sid];
  25.  
  26. inline void upd(int o, int v) {
  27. for(ri i = o; i <= m; i += i & (-i))
  28. t[i] += v;
  29. }
  30.  
  31. inline int qry(int o) {
  32. int ret = ;
  33. for(ri i = o; i; i -= i & (-i))
  34. ret += t[i];
  35. return ret;
  36. }
  37.  
  38. void Solve() {
  39. rep(i, , n)
  40. pre[i] = qry(p[i]), upd(p[i], );
  41. pre[n + ] = -;
  42.  
  43. rep(i, , m) t[i] = ;
  44. for(ri i = , j = ; i <= n; i ++)
  45. {
  46. while(j && qry(p[i]) != pre[j + ])
  47. {
  48. for(ri k = i - j; k < i - nxt[j]; k ++)
  49. upd(p[k], -);
  50. j = nxt[j];
  51. }
  52. if(qry(p[i]) == pre[j + ]) j ++, upd(p[i], );
  53. nxt[i] = j;
  54. }
  55.  
  56. rep(i, , m) t[i] = ;
  57. for(ri i = , j = ; i <= m; i ++)
  58. {
  59. while(j && qry(h[i]) != pre[j + ])
  60. {
  61. for(ri k = i - j; k < i - nxt[j]; k ++)
  62. upd(h[k], -);
  63. j = nxt[j];
  64. }
  65. if(qry(h[i]) == pre[j + ]) j ++, upd(h[i], );
  66. if(j == n) ans[++ tot] = i - n + ;
  67. }
  68. }
  69.  
  70. int main() {
  71.  
  72. n = read(); m = read();
  73. rep(i, , n) p[read()] = i;
  74. rep(i, , m) T[i] = h[i] = read();
  75.  
  76. sort(T + , T + m + );
  77. cm = unique(T + , T + m + ) - T - ;
  78. rep(i, , m) h[i] = lower_bound(T + , T + cm + , h[i]) - T;
  79.  
  80. Solve();
  81. printf("%d\n", tot);
  82. rep(i, , tot) printf("%d ", ans[i]);
  83. printf("\n");
  84. return ;
  85. }

luoguP4696 [CEOI2011]Matching KMP+树状数组的更多相关文章

  1. 【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组

    题目描述 给出两个长度分别为n.m的序列A.B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置. 输入 第一行包含两个整数n, m (2≤n≤m≤1000000).  ...

  2. 【POJ 3167】Cow Patterns (KMP+树状数组)

    Cow Patterns Description A particular subgroup of K (1 <= K <= 25,000) of Farmer John's cows l ...

  3. 【未完】训练赛20190304:KMP+树状数组+线段树+优先队列

    头炸了啊,只做出L题,前两天刚看的Shawn zhou的博客学习的,幸亏看了啊,否则就爆零了,发现题目都是经典题,线段树,KMP,我都没看过,最近又在复习考研,真后悔大一大二没好好学习啊,得抽时间好好 ...

  4. 【poj 3167】Cow Patterns(字符串--KMP匹配+数据结构--树状数组)

    题意:给2个数字序列 a 和 b ,问按从小到达排序后,a中的哪些子串与b的名次匹配. a 的长度 N≤100,000,b的长度 M≤25,000,数字的大小 K≤25. 解法:[思考]1.X 暴力. ...

  5. 【LOJ#2507】[CEOI2011]Matching(KMP,树状数组)

    [LOJ#2507][CEOI2011]Matching(KMP,树状数组) 题面 LOJ 题解 发现要做的是排名串的匹配. 然后我们考虑把它转成这个位置之前有多少个数小于当前这个数,这样子只要每个位 ...

  6. [bzoj1892][bzoj2384][bzoj1461][Ceoi2011]Match/字符串的匹配_KMP_树状数组

    2384: [Ceoi2011]Match 1892: Match 1461: 字符串的匹配 题目大意: 数据范围: 题解: 很巧妙的一道题呀. 需要对$KMP$算法有很深的理解才行. 首先我们需要发 ...

  7. 51nod 1286 三段子串(树状数组+拓展kmp)

    题意: 给定一个字符串S,找到另外一个字符串T,T既是S的前缀,也是S的后缀,并且在中间某个地方也出现一次,并且这三次出现不重合.求T最长的长度. 例如:S = "abababababa&q ...

  8. 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组

    题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...

  9. 【AC自动机】【树状数组】【dfs序】洛谷 P2414 [NOI2011]阿狸的打字机 题解

        这一题是对AC自动机的充分理解和树dfs序的巧妙运用. 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和' ...

随机推荐

  1. 双击CAD对象,显示自定义对话框实现方法

    class TlsApplication : IExtensionApplication { void IExtensionApplication.Initialize() { TTest.Start ...

  2. 【微服务架构】SpringCloud之Ribbon

    一:Ribbon是什么? Ribbon是Netfix发布的开源项目,主要负责客户端的软件负载均衡算法,将Netfix的中间层连接在一起,Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等. ...

  3. 文件读取 FILE

    需要了解的概念 [数据流][缓冲区(Buffer)][文件类型][文件存取方式][借助文件指针读写文件] 需要理解的知识点包括:数据流.缓冲区.文件类型.文件存取方式 1.1 数据流: 指程序与数据的 ...

  4. OGG-01389 File header failed to parse tokens.

    http://blog.csdn.net/zbdba/article/details/44095105; 处理的思路: 1.查看日志 2.在目标端看最新的队列文件的日期,假如没有最新的队列文件就说明源 ...

  5. textarea保留换行和空格

    <style> pre {white-space: pre-wrap;} </style> //替换textare <pre class="feedback_q ...

  6. jquery记忆笔记

    1.javascript需要注意的一些问题: ①不要使用==比较,始终坚持使用===比较. false == 0; // true false === 0; // false ②NaN这个特殊的Num ...

  7. idea心得

    概述 Intellij IDEA真是越用越觉得它强大,它总是在我们写代码的时候,不时给我们来个小惊喜.出于对Intellij IDEA的喜爱,我决定写一个与其相关的专栏或者系列,把一些好用的Intel ...

  8. 使用JS实现2048小游戏

    JS实现2048小游戏源码 效果图: 代码如下,复制即可使用: (适用浏览器:360.FireFox.Chrome.Opera.傲游.搜狗.世界之窗. 不支持Safari.IE8及以下浏览器.) &l ...

  9. Linux下的输入/输出重定向

    Linux环境中支持输入输出重定向,用符号<和>来表示.0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出,比如 2>lee.dat 表示 ...

  10. 四B象限图