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. sql一个表中的数据插入到另外一个表中

    声名:a,b ,都是表 复制代码代码如下: --b表存在(两表结构一样)  insert into b select * from a  若两表只是有部分(字段)相同,则 复制代码代码如下: inse ...

  2. TCP协议学习

    一.TCP参考模型  VS OSI参考模型 二.TCP/IP分层模型的四个协议层分别完成以下的功能 第一层 网络接口层 网络接口层包括用于协作IP数据在已有网络介质上传输的协议.实际上TCP/IP标准 ...

  3. 【转】虚拟机VMware与主机共享文件介绍

    from: http://www.cnblogs.com/kerrycode/p/3818095.html 写的比较详细,但是vm版本较旧. 2:通过共享文件夹功能 虚拟机VMware提供了在宿主机与 ...

  4. elasticsearch5.0及head插件安装

        这个瞎jb整了半天.准备把es2.4升级到5.0,结果老报错 环境:centos6.5+es2.4是ok的换成es5就出毛病.也不能说啥 ,我用的是最新的 源码解压启动时候报错,具体错误for ...

  5. [LeetCode] Odd Even Linked List 奇偶链表

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  6. [LeetCode] 4Sum 四数之和

    Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = tar ...

  7. Spark Rdd coalesce()方法和repartition()方法

    在Spark的Rdd中,Rdd是分区的. 有时候需要重新设置Rdd的分区数量,比如Rdd的分区中,Rdd分区比较多,但是每个Rdd的数据量比较小,需要设置一个比较合理的分区.或者需要把Rdd的分区数量 ...

  8. Jenkins创建Maven项目及SSH部署

    前面我们已经安装了Jenkins的环境,以及配置好了jdk和maven.下面我们来看如何通过Jenkins将svn的项目进行打包和部署. 创建MAVEN项目 1.点击新建,输入项目名,选择" ...

  9. Servlet-Cookie源码分析 源码环境:Tomcat8

    最近在学习servlet的一些实现细节,阅读了Cookie的源码. Cookie本质上是服务器发送给客户端(主要是浏览器)的一个会话临时数据. 其源码注释文档的说明: Creates a cookie ...

  10. json 除去转义字符以及查看json错误

    $param=stripslashes($_POST['param']); try{ //$param包含了文档指定的信息,...这里保存您的快递信息,$param的格式与订阅时指定的格式一致 $ar ...