问题

参考51nod1304这道题;

很显然我们要求的是S的每个后缀与S的最长公共前缀的长度之和。

暴力

假设我们把next[i]表示为第i个后缀与S的最长公共前缀的长度。

现在我们想了:这个next数组,如果暴力来求的话,时间复杂度是O(n2)。

这是我们回忆一下KMP:KMP物尽其用,然后呢就把求fail的速度提高到了O(n)。

那么我们在求next数组的时候,可不可以也使用这样的想法来物尽其用,尽可能地去除重复的匹配呢?

答案是肯定的。

引入扩展KMP



假设要处理出S的next数组,现在已经处理出前s的next了。

现在要求出下一个位置x的next。

其中维护一个li,使得li=max{next[id]}(id∈[1,s])。


由next[id]的定义,我们知道S[id..li]=S[1..next[id]]。

推得S[x..li]=S[1+x−id..next[id]]。

如果id>1,那么1+x−id<x,进一步next[1+x−id]我们已经是知道的了。

于是就有S[x..li]=S[1..next[1+x−id]]。


目前为止,我们很容易看出,x往后的next[1+x−id]这一段是可以不用匹配的。

但我们需要再分类一下:

1.x+next[1+x-id]-1<li

这种情况显然是next[x]=next[1+x−id]。

因为在li范围内,next[1+x−id]是极大的。

所以next[x]不会比next[1+x−id]更大。

2.x+next[1+x-id]-1>=li

这种情况虽然我们可以知道,[x,li]这一段是可以不用匹配的。

但是li以后的情况我们都是未知的。

那么我们暴力匹配来推进li。

于是乎就会有新的li=next[x],id=x。


重复上述过程,我们可以求出所有的next。

显然时间复杂度只与li的推进有关,即为O(n)。

回到本题

使用扩展KMP求出next后,求和即可。

我的博客

扩展KMP的完全体

事实上本题只是扩展KMP的退化。

扩展KMP可以用于求一个串S的所有后缀与目标串T的最长公共前缀的的长度。

想法与求next数组一样。


设要求的东西叫ext。



其中维护一个li,使得li=max{ext[id]}(id∈[1,s])。

同理推得S[x..li]=T[1..next[1+x−id]],其中next关于T。

那么依然分类讨论,即可求出ext。

最后贴上一个求next的程序

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="ex1304.in";
const char* fout="ex1304.out";
const int inf=0x7fffffff;
const int maxn=1000007;
int n,i,j,k,limit,id;
ll ans;
char a[maxn];
int ne[maxn];
int main(){
scanf("%s",a+1);
n=strlen(a+1);
limit=0;
id=0;
ne[1]=n;
for (i=2;i<=n;i++){
j=ne[i-id+1];
if (i+j-1<limit) ne[i]=j;
else{
j=max(0,limit-i+1);
for (;j+i<=n;j++) if (a[i+j]!=a[j+1]) break;
if (i+j-1>limit){
limit=i+j-1;
id=i;
}
ne[i]=j;
}
}
for (i=1;i<=n;i++) ans+=ne[i];
printf("%lld",ans);
return 0;
}

【怪物】KMP畸形变种——扩展KMP的更多相关文章

  1. KMP之Z-function (扩展kmp)

    http://codeforces.com/blog/entry/3107 // s[0, ..., n-1], z[0] = 0// z[i] is the length of the longes ...

  2. 扩展KMP——算法总结,来自于 迷路的鸽子

    扩展kmp                 LRH 所谓扩展kmp指的是与kmp相似的求辅助数组的原理,但是本身与kmp关系不大. 1.exkmp的用途:给定一个主串s和一个子串t,求出s中每一个后缀 ...

  3. 扩展kmp——原创

    扩展kmp                 LRH 所谓扩展kmp指的是与kmp相似的求辅助数组的原理,但是本身与kmp关系不大. 1.exkmp的用途:给定一个主串s和一个子串t,求出s中每一个后缀 ...

  4. 扩展KMP算法

    一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...

  5. 扩展KMP --- HDU 3613 Best Reward

    Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...

  6. KMP和扩展KMP

    文章网上太多这里提一下代码细节: KMP: scanf("%s\n",s); scanf("%s\n",t); int ls=strlen(s),lt=strl ...

  7. UVA5876 Writings on the Wall 扩展KMP

    扩展KMP的简单题. #include<stdio.h> #include<string.h> #define maxn 51010 char s[maxn],t[maxn]; ...

  8. hdu4333 扩展KMP

    慢慢研究可以发现,可以用扩展kmp来求.由于扩展kmp的next[]只有一部分,当前位子前面那部分和母串的后部分,所以可以将字符串复制接在后面一次. 先求如果next[]>0&& ...

  9. 扩展KMP

    刘雅琼论文 http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html 论文讲的非常详细. 给定母串S,子串T,n=strlen(S),m=st ...

随机推荐

  1. 阿里云提供全托管 ZooKeeper

    自 2010 年左右第一次引入以来,Apache ZooKeeper 目前在阿里巴巴集团内部已经有了将近 10 年的发展,使用的场景非常广泛,基于 ZooKeeper 强一致性的特点,被用在了分布式锁 ...

  2. Redis开发及管理实战

    目录 Redis数据类型 字符串 String string类型操作 字典 Hash 列表 List 集合 Set 有序集合 SortedSet 生产消费模型 Redis事务管理 事务命令 示例 Re ...

  3. C语言作用域、链接属性和存储类型

    C/C++中作用域详解 作用域 编译器可以确认的4种作用域-代码块作用域.文件作用域.函数作用域和原型作用域,一般来说,标识符(包括变量名和函数名)声明的位置决定它的作用域. (1)代码块作用域 一对 ...

  4. python 运行python -m pip list 出现错误

    1.出现如下错误提示 2解决方案 解决方法:(windows)在C:\Users{用户名}\ 目录下创建名称为pip的文件夹,里面创建文本文件,内容为 [list] format=columns 保存 ...

  5. 实习面试总结(只写了昨天腾讯的面试和拿到offer的一个小公司, 有空再把前面的补上吧)

    一个月来面了大大小小的公司有近10个,还是总结一下吧,希望对大家有点用处. 我想说的是,大学四年,如果不会继续读研深造,那么你需要做的不仅仅是疯狂的做项目,或者单独的学算法. 最好的方式就是都了解一点 ...

  6. idea使用及其快捷键(Jetbrains很多是通用的)(转)

    Java程序员肯定会使用idea进行开发,因为其非常强大,很好用,而且可以很傻瓜式导入gradle,用来做SSM项目也很简单 学生是可以使用教育邮箱或者上床学生证使用免费的jetbrains全家桶的, ...

  7. 初探.NET CORE WEB API(RESTful风格)

    前面有4篇系列博客 (一)Asp.net web api中的坑-[找不到与请求 URI匹配的 HTTP 资源] (二)Asp.net web api中的坑-[http get请求中的参数] (三)As ...

  8. MATLAB---dir函数

    dir函数是最常用的转换路径的函数,可以获得指定文件夹下的所有子文件夹和文件,并存放在一个文件结构的数组中,这个数组各结构体内容如下: name    -- 文件名 date    -- 修改日期 b ...

  9. 用Python的requests库作接口测试——对响应进行迭代

    使用 requests.Response.iter_lines() 方法,可以很方便地对流式API(例如 Twitter的流式API )的响应进行迭代. 简单地设置 stream 为 True 便可以 ...

  10. TZ_05_Spring_annotation常见注解

    Spring常用的注解大全和解释 注解 解释 @Controller 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类 ...