CH1809匹配统计【KMP】
1809 匹配统计 0x18「基本数据结构」练习
描述
阿轩在纸上写了两个字符串,分别记为A和B。利用在数据结构与算法课上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”与“字符串B”匹配的长度。
不过阿轩是一个勤学好问的同学,他向你提出了Q个问题:在每个问题中,他给定你一个整数x,请你告诉他有多少个位置,满足“字符串A从该位置开始的后缀子串”与B匹配的长度恰好为x。
例如:A=aabcde,B=ab,则A有aabcde、abcde、bcde、cde、de、e这6个后缀子串,它们与B=ab的匹配长度分别是1、2、0、0、0、0。因此A有4个位置与B的匹配长度恰好为0,有1个位置的匹配长度恰好为1,有1个位置的匹配长度恰好为2。
输入格式
第一行三个整数N,M,Q,表示A串长度、B串长度、问题个数。
第二行是字符串A,第三行是字符串B。
接下来Q行每行1个整数x,表示一个问题。
1<=N,M,Q,x<=200000.
输出格式
共Q行,依次表示每个问题的答案。
样例输入
6 2 5
aabcde
ab
0
1
2
3
4
样例输出
4
1
1
0
0
来源
北京大学2015年数据结构与算法A期末考试
题意:一个字符串a, 一个字符串b。对于每一个询问x,问a的后缀中与b匹配长度恰好为x的数量是多少。
思路:开始的时候用了Hash,枚举开始节点,显然会T。还没想到优化。
后来看了题解写了KMP。用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]。
#include <iostream>
#include <set>
#include <cmath>
#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long LL;
#define inf 0x7f7f7f7f
#define pr pair<int, int>
#define mp make_pair int n, m, q;
const int maxn = 2e5 + ;
char a[maxn], b[maxn];
unsigned long long Ha[maxn], Hb[maxn], p[maxn]; int nxt[maxn], f[maxn], cnt[maxn];
void getnxt()
{
nxt[] = ;
for(int i = , j = ; i <= m; i++){
while(j > && b[i] != b[j + ])j = nxt[j];
if(b[i] == b[j + ])j++;
nxt[i] = j;
}
} int main()
{
scanf("%d%d%d", &n, &m, &q);
scanf("%s", a + );
scanf("%s", b + );
getnxt();
for(int i = , j = ; i <= n; i++){
while(j > && (j == m || a[i] != b[j + ]))j = nxt[j];
if(a[i] == b[j + ])j++;
f[i] = j;
}
for(int i = ; i <= n; i++){
cnt[f[i]]++;
}
for(int i = m; i >= ; i--){
cnt[nxt[i]] += cnt[i];
}
/*p[0] = 1;
for(int i = 1; i <= n; i++){
Ha[i] = Ha[i - 1] * 131 + a[i] - 'a' + 1;
Hb[i] = Hb[i - 1] * 131 + b[i] - 'a' + 1;
p[i] = p[i - 1] * 131;
}*/ while(q--){
int x;
scanf("%d", &x);
/*if(x > min(n, m)){
printf("0\n");
continue;
}
int hashb = Hb[x] - Hb[0] * p[x];
int hb = Hb[x + 1] - Hb[0] * p[x + 1];
int cnt = 0;
for(int i = 1; i <= n; i++){
int hasha = Ha[i + x - 1] - Ha[i - 1] * p[x];
int ha = Ha[i + x] - Ha[i - 1] * p[x + 1]; if(hasha == hashb && ha != hb){
cnt++;
}
}*/ printf("%d\n", cnt[x] - cnt[x + ]);
} return ;
}
CH1809匹配统计【KMP】的更多相关文章
- CH1809 匹配统计
题意 描述 阿轩在纸上写了两个字符串,分别记为A和B.利用在数据结构与算法课上学到的知识,他很容易地求出了"字符串A从任意位置开始的后缀子串"与"字符串B"匹配 ...
- CH1809 匹配统计 题解
看了好久才懂,我好菜啊-- 题意:给两个字符串 \(a\) 与 \(b\),对于 \(q\) 次询问,每次询问给出一个 \(x\),求存在多少个位置使得 \(a\) 从该位置开始的后缀子串与 \(b\ ...
- 字符串查找算法总结(暴力匹配、KMP 算法、Boyer-Moore 算法和 Sunday 算法)
字符串匹配是字符串的一种基本操作:给定一个长度为 M 的文本和一个长度为 N 的模式串,在文本中找到一个和该模式相符的子字符串,并返回该字字符串在文本中的位置. KMP 算法,全称是 Knuth-Mo ...
- Leetcode28--->字符串的匹配(KMP)
题目: 题目的本质是给定两个字符串str1,str2,求str1中的str2串开始的地方,即字符串的匹配,KMP算法 思路:时间复杂度为O(m + n),空间复杂度为O(n),原串的长度为m,子串的长 ...
- 【CH1809】匹配统计(KMP)
题目链接 摘自https://www.cnblogs.com/wyboooo/p/9829517.html 用KMP先求出以a[i]为结尾的前缀与b匹配的最长长度. 比如 f[i] = j,就表示a[ ...
- 串的匹配:朴素匹配&KMP算法
引言 字符串的模式匹配是一种经常使用的操作. 模式匹配(pattern matching),简单讲就是在文本(text,或者说母串str)中寻找一给定的模式(pattern).通常文本都非常大.而模式 ...
- 从暴力匹配到KMP算法
前言 现在有两个字符串:\(s1\)和\(s2\),现在要你输出\(s2\)在\(s1\)当中每一次出现的位置,你会怎么做? 暴力匹配算法 基本思路 用两个指针分别指向当前匹配到的位置,并对当前状态进 ...
- AcWing 160. 匹配统计 (哈希+二分) 打卡
阿轩在纸上写了两个字符串,分别记为A和B. 利用在数据结构与算法课上学到的知识,他很容易地求出了“字符串A从任意位置开始的后缀子串”与“字符串B”匹配的长度. 不过阿轩是一个勤学好问的同学,他向你提出 ...
- 算法之匹配:KMP
public static int getIndexOf(String str1, String str2) { if (str1 == null || str2 == null || str1.le ...
随机推荐
- 【转载】ASP.NET Core 中间件详解及项目实战
前言 在上篇文章主要介绍了DotNetCore项目状况,本篇文章是我们在开发自己的项目中实际使用的,比较贴合实际应用,算是对中间件的一个深入使用了,不是简单的Hello World,如果你觉得本篇文章 ...
- unity3d绘画手册-------地形各个参数解释
关于Unity3D是什么.我就不多做解释了.由于工作原因,该系列原创教程不定期更新.每月必然有更新.谢谢各位. Unity地形:: 新建地形: <ignore_js_op> 如图在菜单中新 ...
- 【Java面试题】10 abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
1.abstract是抽象的,指的是方法只有声明而没有实现,他的实现要放入声明该类的子类中实现. 2.static是静态的,是一种属于类而不属于对象的方法或者属性 3.synchronized 是同步 ...
- php将汉字转换为拼音和得到词语首字母(二)
<?php class Pinyin{ private $_outEncoding = "GB2312"; public function getPinyin($str,$p ...
- PHP+tcpdf的生成
项目中,可能用到额 查看:http://www.sucaihuo.com/php/217.html
- MathType使用中的四个小技巧
MathType是一种比较常见的数学公式编辑器,常常与office搭配着使用,我们在使用的时候有一些要注意的小技巧,下面我们就来给大家介绍介绍MathType使用中的四个小技巧? 技巧一:调整工具栏显 ...
- 安装Phoenix时./sqlline.py执行报错File "./sqlline.py", line 27, in <module> import argparse ImportError: No module named argparse解决办法(图文详解)
不多说,直接上干货! 前期博客 Apache版Phoenix的安装(图文详解) 问题现象 Traceback (most recent call last): File , in <module ...
- 工作流JBPM_day01:2-HelloWorld
工作流JBPM_day01:2-HelloWorld 新建一个java工程Jbpm4.4 拷贝helloworld.jpdl.xml和helloworld.png文件出来压缩成helloworld.z ...
- angularjs基础——控制器
1)当使用非空ng-app和ng-controller时,变量由angularjs控制器来处理 2)控制器接管模型变量后,直接修改模型,模版里的变量还是会自动变的 <!DOCTYPE html& ...
- Python 入门(一)定义字符串+raw字符串与多行字符串
定义字符串 前面我们讲解了什么是字符串.字符串可以用''或者""括起来表示. 如果字符串本身包含'怎么办?比如我们要表示字符串 I'm OK ,这时,可以用" " ...