题目链接

摘自https://www.cnblogs.com/wyboooo/p/9829517.html

用KMP先求出以a[i]为结尾的前缀与b匹配的最长长度。
比如 f[i] = j,就表示a[1~i]的后缀最多可以和b[1~j]匹配。但求出这个并不意味着以a[i]为开头的后缀可以和b恰好匹配j位(因为也许后面还可以匹配),但是可以肯定的是他至少可以匹配j位。我们很难求出恰好可以匹配x位的位置有多少,但是我们可以存至少可以匹配x位的位置的数目,结果用cnt[x] - cnt[x +1]就可以了。
因此cnt[f[i]] ++就很显然了。
由于我们之前求出的是最长长度,因此当a[1~i]可以最多和b[1~j]匹配时,也一定存在一个小于j的k使得a[1~i]和b[1~k]匹配,也就是一定能找到一个位置,至少匹配k位,但这个可能我们在之前没有加上过。而这个k恰好就等于nxt[j]。

xjc大佬还提出了一个hash+二分的做法,也能AC。

就是用二分长度+hash check求出每个位置的答案,然后直接用桶记录秒出答案。

时间复杂度\(O(n\log n)\)

#include <cstdio>
#include <cstring>
#define Open(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout);
const int MAXN = 200010;
int nxt[MAXN], n, m, q, f[MAXN], c[MAXN], d;
char a[MAXN], b[MAXN];
int main(){
Open("str");
scanf("%d%d%d%s%s", &n, &m, &q, a + 1, b + 1);
int j = 0;
for(int i = 2; i <= m; ++i){
while(j && b[i] != b[j + 1]) j = nxt[j];
if(b[j + 1] == b[i]) ++j;
nxt[i] = j;
}
j = 0;
for(int i = 1; i <= n; ++i){
while(j && (a[i] != b[j + 1] || j == m)) j = nxt[j];
if(a[i] == b[j + 1]) ++j;
f[i] = j;
}
for(int i = 1; i <= n; ++i)
++c[f[i]];
for(int i = m; i; --i)
c[nxt[i]] += c[i];
for(int i = 1; i <= q; ++i){
scanf("%d", &d);
printf("%d\n", c[d] - c[d + 1]);
}
return 0;
}

【CH1809】匹配统计(KMP)的更多相关文章

  1. CH1809匹配统计【KMP】

    1809 匹配统计 0x18「基本数据结构」练习 描述 阿轩在纸上写了两个字符串,分别记为A和B.利用在数据结构与算法课上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”与“字符串B” ...

  2. CH1809 匹配统计

    题意 描述 阿轩在纸上写了两个字符串,分别记为A和B.利用在数据结构与算法课上学到的知识,他很容易地求出了"字符串A从任意位置开始的后缀子串"与"字符串B"匹配 ...

  3. CH1809 匹配统计 题解

    看了好久才懂,我好菜啊-- 题意:给两个字符串 \(a\) 与 \(b\),对于 \(q\) 次询问,每次询问给出一个 \(x\),求存在多少个位置使得 \(a\) 从该位置开始的后缀子串与 \(b\ ...

  4. 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)

    字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...

  5. Leetcode28--->字符串的匹配(KMP)

    题目: 题目的本质是给定两个字符串str1,str2,求str1中的str2串开始的地方,即字符串的匹配,KMP算法 思路:时间复杂度为O(m + n),空间复杂度为O(n),原串的长度为m,子串的长 ...

  6. 串的匹配:朴素匹配&amp;KMP算法

    引言 字符串的模式匹配是一种经常使用的操作. 模式匹配(pattern matching),简单讲就是在文本(text,或者说母串str)中寻找一给定的模式(pattern).通常文本都非常大.而模式 ...

  7. 从暴力匹配到KMP算法

    前言 现在有两个字符串:\(s1\)和\(s2\),现在要你输出\(s2\)在\(s1\)当中每一次出现的位置,你会怎么做? 暴力匹配算法 基本思路 用两个指针分别指向当前匹配到的位置,并对当前状态进 ...

  8. AcWing 160. 匹配统计 (哈希+二分) 打卡

    阿轩在纸上写了两个字符串,分别记为A和B. 利用在数据结构与算法课上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”与“字符串B”匹配的长度. 不过阿轩是一个勤学好问的同学,他向你提出 ...

  9. 算法之匹配:KMP

    public static int getIndexOf(String str1, String str2) { if (str1 == null || str2 == null || str1.le ...

随机推荐

  1. 刷题记录:[LCTF]bestphp's revenge

    目录 刷题记录:[LCTF]bestphp's revenge 一.知识点 1.SoapClient触发反序列化导致ssrf 2.serialize_hander处理session方式不同导致sess ...

  2. 第06组 Beta冲刺(2/5)

    队名:拾光组 组长博客链接 作业博客链接 团队项目情况 燃尽图(组内共享) 组长:宋奕 过去两天完成了哪些任务 维护后端代码 学习后端架构 GitHub签入记录 接下来的计划 维护后端代码,跟进组员完 ...

  3. MacOS Laravel 安装教程

    一.到官网选择 Laravel 版本 根据个人的喜好选择安装的版本,我选择的是 5.8 https://laravel.com/docs/5.8/installation 以下是 Laravel 5. ...

  4. typescript - 9.装饰器

    装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为. 通俗的讲装饰器就是一个方法,可以注入到类.方法.属性参数上来扩展类.属性.方法.参数的功能. 常见的装 ...

  5. Node add Test1

    root_group->addChild(node22); osg::Vec3f vec3f1 = node22->getBound().center(); osg::NodePathLi ...

  6. 泡泡一分钟:GEN-SLAM - Generative Modeling for Monocular Simultaneous Localization and Mapping

    张宁  GEN-SLAM - Generative Modeling for Monocular Simultaneous Localization and Mapping GEN-SLAM  - 单 ...

  7. [LeetCode] 67. Add Binary 二进制数相加

    Given two binary strings, return their sum (also a binary string). The input strings are both non-em ...

  8. [LeetCode] 774. Minimize Max Distance to Gas Station 最小化加油站间的最大距离

    On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., statio ...

  9. Laravel 数据库实例教程 —— 使用查询构建器对数据库进行增删改查

    原文地址:https://blog.csdn.net/lmy_love_/article/details/72832259 获取查询构建器很简单,还是要依赖DB门面,我们使用DB门面的table方法, ...

  10. 面试之leetcode分治-求众数,x幂等

    1 leetcode50 计算 x 的 n 次幂函数. 实现 pow(x, n) ,即计算 x 的 n 次幂函数. (1)调用库函数 (2)暴力o(N) (3)分治 xxxxxx.......x    ...