KMP专题
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 ;
}
题意:如果字符串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专题的更多相关文章
- (字典树)How many--hdu--2609
http://acm.hdu.edu.cn/showproblem.php?pid=2609 How many Time Limit: 2000/1000 MS (Java/Others) Me ...
- 9.14[XJOI] NOIP训练33
今日9.14 洛谷打卡:大凶!!!(换个字体玩玩qwq) -------------------------------------------------------- 一个超颓的上午 今天又是fl ...
- [一本通学习笔记] AC自动机
AC自动机可以看作是在Trie树上建立了fail指针,在这里可以看作fail链.如果u的fail链指向v,那么v的对应串一定是u对应串在所给定字符串集合的后缀集合中的最长的后缀. 我们考虑一下如何实现 ...
- 字符串专题:KMP POJ 3561
http://poj.org/problem?id=3461 KMP这里讲的不错next的求法值得借鉴 http://blog.sina.com.cn/s/blog_70bab9230101g0qv. ...
- kmp算法专题总结
next数组的含义:next[i]表示以字符串s的第i个字符为结尾的后缀与s前缀匹配的长度 next数组也可以当做fail数组,即当模式串s[j]与串t[i]不匹配时,只要将j转换到next[j]继续 ...
- acm专题---KMP模板
KMP的子串长n,模式串长m,复杂度o(m+n),朴素做法的复杂度o((n-m+1)*m) 觉得大话数据结果上面这个讲得特别好 改进版本的KMP leetcode 28. Implement strS ...
- 2015 UESTC 搜索专题K题 秋实大哥の恋爱物语 kmp
秋实大哥の恋爱物语 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 De ...
- 2015 UESTC 搜索专题J题 全都是秋实大哥 kmp
全都是秋实大哥 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/61 Desc ...
- kuangbin专题16I(kmp)
题目链接: https://vjudge.net/contest/70325#problem/I 题意: 求多个字符串的最长公共子串, 有多个则输出字典序最小的. 思路: 这里的字符串长度固定为 60 ...
随机推荐
- Linux NFS服务器的安装与配置
一.NFS服务简介 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操 ...
- 史上最全QC学习方案,值得收藏!
Quality Center是一个基于Web的强大的测试管理工具,可以组织和管理应用程序测试流程的所有阶段,**制定测试需求.计划测试.执行测试和跟踪缺陷.此外,通过Quality Center还可以 ...
- Apache服务停止:信号灯超时时间已到,指定的网络名不再可用
环境说明:Apache2.4.10,Windows Server 2008 R2 问题说明: apache服务用于下载文件,但是在运行一段时间后,突然挂了. 其错误提示如下所示: [error] (7 ...
- 常用算法——排序(二)
简单选择排序法 选择排序(Selection Sort)的基本思想:对n个记录进行扫描,选择最小的记录,将其输出,接着在剩下的n-1个记录中扫描,选择最小的记录将其输出,--不断重复这个过程,直到只剩 ...
- python读取文件夹
import os def getFiles(rootDir): if os.path.isfile(rootDir): print(rootDir) elif os.path.isdir(rootD ...
- ngx_http_fastcgi_module模块.md
ngx_http_fastcgi_module ngx_http_fastcgi_module模块允许将请求传递到FastCGI服务器. fastcgi_bind Syntax: fastcgi_bi ...
- CODE[VS]1372DNA
Description 为了进一步分析外星生物,专家们决定对 DNA 进行切割.限制性核酸内切酶是基因工程中的重要的工具酶.它会识别一段碱基序列(说白了就是只包含 ATGC 的序列)并且切割开.Eco ...
- pcl曲面重建模块-poisson重建算法示例
poisson曲面重建算法 pcl-1.8测试通过 #include <iostream> #include <pcl/common/common.h> #include &l ...
- UVA10304
全部遍历.设置两个下标,若相同i++,j++,不相同则j++. #include<stdio.h> #include<string.h> int main(){ ]; ]; s ...
- font-size 兼容问题
早年~ 楔子 在为“我的抵扣券”添加 按钮时,为了将文字隐掉,给节点设置了“font-size:0;”,设置后刷一下浏览器,webkit下按钮掉下去了,而其他浏览器(包括IE6/7)都正常: 按理说 ...