1、【HDU 3336】Count the string(KMP+dp)

题意:求给定字符串含前缀的数量,如输入字符串abab,前缀是a、ab、aba、abab,在原字符串中出现的次数分别是2、2、1、1,所以答案是2+2+1+1=6.

解题思路:s[]=abcdabcdabcdea ==> f[] = 00001234567801,f[i]=k的含义是s[i-k]=s[i],dp[i]=dp[f[i]]+1,dp[i]表示以s[i]结尾的前缀的数量

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define ll __int64
const int N=*1e5+;
const ll mod=;
char p[N];
ll f[N], ans[N];
int lenp;
void getf()
{
memset(f, , sizeof(f));
int i,j;
j=f[]=;
i=;
while(i<lenp)
{
while(!=j && p[i+]!=p[j+]) j=f[j];
if(p[i+] == p[j+]) j++;
f[++i] = j;
}
}
int main(){
int t;
scanf("%d", &t);
while(t--){
memset(ans, , sizeof(ans));
memset(p, '\0', sizeof(p));
scanf("%d%s", &lenp, p+);
getf();
ll sum=;
for(int i=; i<=lenp; i++) ans[i] = (ans[f[i]]+)%mod;
for(int i=; i<=lenp; i++) sum = (sum+ans[i])%mod;
printf("%I64d\n", sum);
// for(int i=1; i<=lenp; i++) cout<<f[i];
//\ cout<<endl;
}
return ;
}

2、【POJ 2406】Power Strings

题意:如果字符串a=”abc”,字符串b=”def”,那么a*b=”abcdef”,输入字符串s,那么s=x^n中n的最大值。

解题思路:求n的最大值也就是求s的最小循环节【s[]=abcdabcdabcdea ==> f[] = 00001234567801,最小循环节只能是len-f[len]】然后判断len是否能整除最小循环节,如果不能整除,那么n最大值只能是1

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
const int N=;
char s[N];
int f[N], lens;
void getf(){
memset(f, , sizeof(f));
int i, j;
j=f[]=-;
i=;
while(i<lens){
while(j!=- && s[i+]!=s[j+]) j = f[j];
f[++i] = ++j;
}
}
int main(){
while(~scanf("%s", s)){
lens = strlen(s);
if(lens== && s[]=='.') break;
getf();
f[lens-]++;
int ans = lens-f[lens-];
if(lens%ans==) ans = lens/ans;
else ans=;
printf("%d\n", ans); }
return ;
}

3、【HDU 1867】A + B for you again

题意:输入两个字符串(len<=1e5)A、B,s1=A+B【去掉了A的后缀跟B的前缀相等部分】,s2=B+A【去掉了B的后缀跟A的前缀相等部分】,输出s1跟s2其中一个,先考虑长度小的,长度差相等的时候考虑字典序小的。

解题思路:关键是求出A的后缀与B的前缀以及B的后缀跟A的前缀重叠部分的长度。A的后缀跟B的前缀重叠部分的求法:求出B的fp[],拿B去匹配A,如果能一直匹配到最后一位,那么重叠部分就是B已经匹配了的长度。

 #include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
const int N=1e5+;
char s[N], p[N];
int fs[N], fp[N], lens, lenp;
void kmp_getfs(){
memset(fs, , sizeof(fs));
int i, j;
i=, j=fs[]=;
while(i<=lens){
while(j!= && s[i]!=s[j+]) j = fs[j];
if(s[i] == s[j+]) j++;
fs[i++]=j;
}
}
void kmp_getfp(){
memset(fp, , sizeof(fp));
int i, j;
i=, j=fp[]=;
while(i<=lenp){
while(j!= && p[i]!=p[j+]) j=fp[j];
if(p[i] == p[j+]) j++;
fp[i++] = j;
}
}
int main(){
while(~scanf("%s%s", s+, p+)){
lens = strlen(s+);
lenp = strlen(p+);
kmp_getfs();
kmp_getfp();
int is=, jp=, flags=;
for(is=; is<=lens; is++){
while(jp!= && s[is]!=p[jp+]) jp=fp[jp];
if(s[is]==p[jp+]){
jp++;
if(is==lens) flags=;
}
}
int ip=, js=, flagp=;
for(ip=; ip<=lenp; ip++){
while(js!= && p[ip]!=s[js+]) js = fs[js];
if(p[ip] == s[js+]){
js++;
if(ip==lenp) flagp=;
}
}
int sums=lens+lenp-jp;
int sump=lens+lenp-js;
if(sums==sump){
string sp, ps;
sp.clear(), ps.clear();
for(int i=; i<=lens; i++) sp+=s[i];
for(int i=jp+; i<=lenp; i++) sp+=p[i];
for(int i=; i<=lenp; i++) ps+=p[i];
for(int i=js+; i<=lens; i++) ps+=s[i];
if(sp>ps) cout<<ps<<endl;
else cout<<sp<<endl;
}
else if(sums>sump){
printf("%s", p+);
for(int i=js+; i<=lens; i++) cout<<s[i];
cout<<endl;
}
else if(sums<sump){
printf("%s", s+);
for(int i=jp+; i<=lenp; i++) cout<<p[i];
cout<<endl;
}
}
return ;
}

KMP专题的更多相关文章

  1. (字典树)How many--hdu--2609

    http://acm.hdu.edu.cn/showproblem.php?pid=2609 How many Time Limit: 2000/1000 MS (Java/Others)    Me ...

  2. 9.14[XJOI] NOIP训练33

    今日9.14 洛谷打卡:大凶!!!(换个字体玩玩qwq) -------------------------------------------------------- 一个超颓的上午 今天又是fl ...

  3. [一本通学习笔记] AC自动机

    AC自动机可以看作是在Trie树上建立了fail指针,在这里可以看作fail链.如果u的fail链指向v,那么v的对应串一定是u对应串在所给定字符串集合的后缀集合中的最长的后缀. 我们考虑一下如何实现 ...

  4. 字符串专题:KMP POJ 3561

    http://poj.org/problem?id=3461 KMP这里讲的不错next的求法值得借鉴 http://blog.sina.com.cn/s/blog_70bab9230101g0qv. ...

  5. kmp算法专题总结

    next数组的含义:next[i]表示以字符串s的第i个字符为结尾的后缀与s前缀匹配的长度 next数组也可以当做fail数组,即当模式串s[j]与串t[i]不匹配时,只要将j转换到next[j]继续 ...

  6. acm专题---KMP模板

    KMP的子串长n,模式串长m,复杂度o(m+n),朴素做法的复杂度o((n-m+1)*m) 觉得大话数据结果上面这个讲得特别好 改进版本的KMP leetcode 28. Implement strS ...

  7. 2015 UESTC 搜索专题K题 秋实大哥の恋爱物语 kmp

    秋实大哥の恋爱物语 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 De ...

  8. 2015 UESTC 搜索专题J题 全都是秋实大哥 kmp

    全都是秋实大哥 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Desc ...

  9. kuangbin专题16I(kmp)

    题目链接: https://vjudge.net/contest/70325#problem/I 题意: 求多个字符串的最长公共子串, 有多个则输出字典序最小的. 思路: 这里的字符串长度固定为 60 ...

随机推荐

  1. IT技术思维导图

    在网上看到有个人总结的java技术的东东,觉得很好,就保存下来了,码农还真是累啊,只有不断的学习才能有所提高,才能拿更多的RMB啊. java技术思维导图 服务端思维导图 前端思维导图

  2. 任意半径局部直方图类算法在PC中快速实现的框架。

    在图像处理中,局部算法一般来说,在很大程度上会获得比全局算法更为好的效果,因为他考虑到了图像领域像素的信息,而很多局部算法可以借助于直方图获得加速.同时,一些常规的算法,比如中值滤波.最大值滤波.最小 ...

  3. 四种比较简单的图像显著性区域特征提取方法原理及实现-----> AC/HC/LC/FT。

    laviewpbt  2014.8.4 编辑 Email:laviewpbt@sina.com   QQ:33184777 最近闲来蛋痛,看了一些显著性检测的文章,只是简单的看看,并没有深入的研究,以 ...

  4. 解决ASP.NET上传文件大小限制

    第一种方法,主要适用于IIS6.0版本 一.修改配置Web.Config文件中的httpRuntime节点对于asp.net,默认只允许上传4M文件,增加如下配置,一般可以自定义最大文件大小.一.修改 ...

  5. [LeetCode] Factorial Trailing Zeroes 求阶乘末尾零的个数

    Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in log ...

  6. C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)

    前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. 本文原创地址:http://www.cnblog ...

  7. Ubuntu apache2.4 设置虚拟主机

    每次重装系统如何配置都上网找,搞半天,都是不对的,还不如自己记下来,以作参考呢.我的项目目录是 /home/feiffy/demo/test,映射的域名是 test.com,这样在浏览器输入 test ...

  8. HTML 基础知识

    HTML 语言格式:1<标签名>内容</标签名> <标签名 属性>2<标签名></标签名>3<标签名/> 知识点:静态与动态网页 ...

  9. 2016总结&2017计划

    2016总结 总体而言,上半年比较勤快,下半年偷懒了.下半年仔细看了Barfoot的书<state estimation for robotics>,收获很大. 2017计划 目前打算写以 ...

  10. 使用Mysql Workbench 画E-R图

    MySQL Workbench 是一款专为MySQL设计的ER/数据库建模工具.你可以用MySQL Workbench设计和创建新的数据库图示,建立数据库文档,以及进行复杂的MySQL 迁移.这里介绍 ...