描述

给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度。
给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个。
N,M,K<=200000

输入格式

第一行三个数 N,M,K,表示A的长度、B的长度和询问数。
第二行为串A。
第三行为串B。
接下来K行,每行1个数X。

输出格式

对于每个询问输出一个数。

测试样例1

输入

6 2 2 
aabcde 
ab 

2

输出


1

代码

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
char a[], b[];
int next[];
int used[];
int num[];
int kmp[]; int main(int argc, char **argv)
{
int i, j;
int l1, l2, s;
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
scanf("%d%d%d\n", &l1, &l2, &s);
scanf("%s\n%s", a, b); i = , j = -;
next[] = -;
while(i < l2){
if(j == - || b[i] == b[j]){
if(b[i + ] == b[j + ]){
next[i + ] = next[j + ];
}else{
next[i + ] = j + ;
}
kmp[i + ] = j + ;
i++, j++;
}else{
j = next[j];
}
} i = , j = ;
while(i < l1){
if(j == - || a[i] == b[j]){
num[i] = j + ;
used[j + ]++;
i++, j++;
}else{
j = next[j];
}
}
for(i = l2; i >= ; i--){
used[kmp[i]] += used[i];
}
for(i = ; i < s; i++){
scanf("%d", &j);
printf("%d\n", used[j] - used[j + ]);
}
return ;
}

转载代码,下面题解(也是转载的)才重要

首先,这个题如果想要求出从每个位置开始的字串的匹配长度,那么O(n^2)以内的算法应该是很难的。但是,这个题要求的并不是“每个位置的长度”,而是“具有这样长度的位置数”。因而,灵活使用KMP算法自我匹配的性质,就能够解决这个问题。

考虑下面的例子:
A串:abbabbabababbababba
B串:abbabababba

应用KMP算法,很容易得到B串的自我匹配是
元素 a b b a b a b a b b  a
位置 1 2 3 4 5 6 7 8 9 10 11
长度 0 0 0 1 2 1 2 1 2 3  4
这个数组记为kmp[位置] = 匹配长度。

由此求得到A串的各个元素尾部的匹配长度是
a b b a b b a b a b a b b  a  b a b b a
1 2 3 4 5 3 4 5 6 7 8 9 10 11 5 6 7 3 4

统计出各个长度的出现频数
长度 0 1 2 3 4 5 6 7 8 9 10 11
频数 0 1 1 3 3 3 2 2 1 1 1  1
这个数组记作cnt[长度] = 频数。

根据KMP自我匹配数组的性质,如果以A串某个元素结尾有一个长度为11的字串可以与B串匹配的话,以该元素结尾的长度为kmp[11] = 4的字串也是可以匹配的。所以说cnt[4] += cnt[11]。也就是说,进行这样的操作

for (i = N; i >= 1; i--)
  cnt[kmp[i]] += cnt[i];

for i := N downto 1 do
 inc( cnt[ kmp[i] ] , cnt[i] );
//转载者注,inc(i)==i++
之后,cnt[i]中保存的就应该是所有长度为i的匹配字串了。这时cnt数组的状态是

长度 0  1 2 3 4 5 6 7 8 9 10 11
频数 19 8 7 4 4 3 2 2 1 1 1  1

然而题中要求的是“长度恰好为i”的子串的个数,也就是这些字串的下一个字符是不能匹配的。然而,cnt数组中存储的cnt[i],必然包含了cnt[i + 1]及以上的情况。然而这很简单,“长度恰好为i”的字串数量就是cnt[i] - cnt[i + 1],因为cnt[i]中可以扩展的字串必然都包含于cnt[i + 1]。

TYVJ P1068 STR Label:KMP匹配 不懂的更多相关文章

  1. TYVJ P1072 bomb Label:看不懂题意

    描述 一场战争正在A国与B国之间如火如荼的展开.B国凭借其强大的经济实力开发出了无数的远程攻击导弹,B国的领导人希望,通过这些导弹直接毁灭A国的指挥部,从而取得战斗的胜利!当然,A国人民不会允许这样的 ...

  2. kmp匹配详解

    字符串算法都是毒瘤的 一.kmp算法的用处 在文本串中查找模式串的位置,数量 文本串:要在这个字符串查找模式串 模式串:在文本串中查找的字符串 全是废话 二.kmp算法的思想 话说kmp好像是3个发明 ...

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

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

  4. BNUOJ-26580 Software Bugs KMP匹配,维护

    题目链接:http://www.bnuoj.com/bnuoj/problem_show.php?pid=26580 题意:给一个模式串,然后m个匹配串,要求删掉匹配串中的所有存在的模式串,使得余下的 ...

  5. TYVJ P1077 有理逼近 Label:坑,tle的好帮手 不懂

    描述 对于一个素数P,我们可以用一系列有理分数(分子.分母都是不大于N的自然数)来逼近sqrt(p),例如P=2,N=5的时候:1/1<5/4<4/3<sqrt(2)<3/2& ...

  6. 求NEXT数组和KMP匹配的两种写法

    注释掉的是我不喜欢的写法. //计算串str的next数组 void getnext(char *str){ int len=strlen(str); ,k=-; next[]=-; while(j& ...

  7. KMP匹配(模板)

    先粘上我入门KMP时看的大佬的博客:orz orz 从头到尾彻底理解KMP 我觉得这篇已经讲的很详细了,希望大家能坚持看下去. 步骤 ①寻找前缀后缀最长公共元素长度对于P = p0 p1 ...pj- ...

  8. $("label + input") 匹配所有紧接在 prev 元素后的 next 元素

    描述: 匹配所有跟在 label 后面的 input 元素 HTML 代码: <form> <label>Name:</label> <input name= ...

  9. 字符串旋转(str.find()---KMP)

    此题旋转带有技巧性,问题转化为常见的问题,熟练STL可以直接用str.find()函数,其是主要想用KMP算法实现字符串的查找算法... //如果对于一个字符串A,将A的前面任意一部分挪到后边去形成的 ...

随机推荐

  1. easyui-datagrid 两次请求

    原因分析及解决方案 html代码中利用class声明了datagrid,导致easyUI解析class代码的时候先解析class声明中的datagrid,这样组件就请求了一次url:然后又调用js初始 ...

  2. 【leetcode】Palindrome Partitioning II

    Palindrome Partitioning II Given a string s, partition s such that every substring of the partition ...

  3. Python操作Mysql实例代码教程在线版(查询手册)

    本文介绍了Python操作MYSQL.执行SQL语句.获取结果集.遍历结果集.取得某个字段.获取表字段名.将图片插入数据库.执行事务等各种代码实例和详细介绍,代码居多,是一桌丰盛唯美的代码大餐   实 ...

  4. apache一个IP多个站点的配置方法

    在日常的网站发布中很多情况下都无法做到一个IP对应一个站点,在IP4的情况下IP的资源是相对有限的.然而作为最流行的Apache自然也考虑到这种情况,那么接下来看看apache服务器怎么配置一个IP多 ...

  5. After Effects的4种抠像插件比较分析

    前景 背景 1.keylight(1.2) 2.Primatee Keyer Pro4.0 3.Zbig [边界生硬] 4.Power Matte v2 [速度很慢,边界生硬]

  6. [Android UI] ProgressBar自定义

    转载自:http://gundumw100.iteye.com/blog/1289348 1: 在JAVA代码中 在java代码中 ProgressBar      继承自View, 在android ...

  7. fedora 添加其他操作系统到 GRUB 2 菜单

    # yum install os-prober # grub2-mkconfig -o /boot/grub2/grub.cfg

  8. vector容器+iterator迭代器

    关于vector容器的详细描述,可参考:http://www.jb51.net/article/41648.htm   关于iterator迭代器的描述,可参考http://www.cppblog.c ...

  9. 自定义viewgroup实现ArcMenu

    最终效果如下 实现思路 通过效果图,会有几个问题: a.动画效果如何实现 可以看出动画是从顶点外外发射的,可能有人说,那还不简单,默认元素都在定点位置,然后TraslateAnimation就好了:这 ...

  10. 【转】如何在 Eclipse 中進行 TFS 的版本管控

    转自:http://www.dotblogs.com.tw/franma/archive/2010/05/04/15009.aspx 和上一篇一樣!所使用的版本也是 3.4 的 之前有被問到 Team ...