蓝书2.2 KMP算法
T1 Radio Transmission bzoj 1355
题目大意:
一个字符串,它是由某个字符串不断自我连接形成的
但是这个字符串是不确定的,现在只想知道它的最短长度是多少
思路:
kmp 输出n-nxt[n]
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 1000100
const int MOD=1e9+;
const int bas=;
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,nxt[MAXN];
char ch[MAXN];
int main()
{
n=read();scanf("%s",ch+);
for(int j=,i=;i<=n;i++)
{
while(ch[i+]!=ch[j+]&&j) j=nxt[j];
if(ch[i+]==ch[j+]) j++;
nxt[i+]=j;
}
printf("%d",n-nxt[n]);
}
T2 OKR-Periods of Words bzoj 1511
题目大意:
求一个串的所有前缀的最长周期(不算自己)长度之和
思路:
求出nxt后不断向前跳 用i减去跳过之后的nxt
不能用最短循环节累计的例子: abcdaa
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 1000100
const int MOD=1e9+;
const int bas=;
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,nxt[MAXN];
ll ans;
char ch[MAXN];
int main()
{
n=read();scanf("%s",ch+);
for(int j=,i=;i<=n;i++)
{
while(ch[i+]!=ch[j+]&&j) j=nxt[j];
if(ch[i+]==ch[j+]) j++;
nxt[i+]=j;
}
for(int i=;i<=n;i++)
{
if(!nxt[i]) continue;
while(nxt[nxt[i]]) nxt[i]=nxt[nxt[i]];
ans+=i-nxt[i];
}
printf("%lld",ans);
}
T3 似乎在梦中见过的样子 bzoj 3620
题目大意:
找出串中所有形如A+B+A的子串 len(A)>=k,len(B)>=1
思路:
每个点为起始点 做n遍kmp
每个终止点只需要判断是否存在nxt使border大于等于k且小于子串长度一半
奇奇怪怪的复杂度
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 15100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,nxt[MAXN],k;
ll ans;
char ch[MAXN];
int main()
{
scanf("%s",ch+);n=strlen(ch+),k=read();
for(int t=;t+*k<=n;t++)
{
nxt[t-]=nxt[t]=t-;
for(int j=t-,i=t;i<=n;i++)
{
while(ch[i+]!=ch[j+]&&j>=t) j=nxt[j];
if(ch[i+]==ch[j+]) j++;
nxt[i+]=j;
}
for(int i=t+*k;i<=n;i++)
{
int x=nxt[i];
while(*(x-t+)>=i-t+) x=nxt[x];
if(x-t+>=k) ans++;
}
}
printf("%lld",ans);
}
T4 Censoring bzoj 3942
题目大意:
有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程
输出最后的S串
思路:
先nxt处理T 然后用一个手打栈记录U串
记录每个位置匹配到T的位置
匹配即可
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<set>
#define inf 2139062143
#define ll long long
#define MAXN 1100100
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-;ch=getchar();}
while(isdigit(ch)) {x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,nxt[MAXN],top,pos[MAXN];
ll ans;
char ch[MAXN],s[MAXN],st[MAXN];
int main()
{
scanf("%s",s+);scanf("%s",ch+);
n=strlen(s+),m=strlen(ch+);
for(int j=,i=;i<=m;i++)
{
while(ch[i+]!=ch[j+]&&j) j=nxt[j];
if(ch[i+]==ch[j+]) j++;
nxt[i+]=j;
}
for(int j=,i=,x;i<=n;i++)
{
st[++top]=s[i],pos[top]=pos[top-];
while(st[top]!=ch[pos[top]+]&&pos[top]) pos[top]=nxt[pos[top]];
if(st[top]==ch[pos[top]+]) pos[top]++;
if(pos[top]==m) top-=m;
}
for(int i=;i<=top;i++) printf("%c",st[i]);
}
蓝书2.2 KMP算法的更多相关文章
- 蓝书3.3 SPFA算法的优化
T1 最小圈 bzoj 1486 题目大意: 一个环的权值平均值为定义为一个这个环上所有边的权值和除以边数 求最小的环的权值平均值 思路: 二分一个值 把所有边减去这个值 判断是否有负环 #inclu ...
- KMP算法总结
kmp算法的T子字符串的下标的变化规律 大话数据结构这边书中的KMP算法的讲解跟最终的算法代码还是有很大的差别 java语言只会if判断语句,循环语句,但是这些语句以及可以包罗万象了,可以适用很多情况 ...
- 51NOD 1292 1277(KMP算法,字符串中的有限状态自动机)
在前两天的CCPC网络赛中...被一发KMP题卡了住了...遂决定,哪里跌倒就在哪里爬起来...把个KMP恶补一发,连带着把AC自动机什么的也整上. 首先,介绍设定:KMP算法计划解决的基本问题是,两 ...
- (原创)详解KMP算法
KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年压根就没看懂过~~~ 之后也在很多地方也都经常看到讲解KMP算法的文章,看久了好像也知道是怎么 ...
- 【模式匹配】KMP算法的来龙去脉
1. 引言 字符串匹配是极为常见的一种模式匹配.简单地说,就是判断主串\(T\)中是否出现该模式串\(P\),即\(P\)为\(T\)的子串.特别地,定义主串为\(T[0 \dots n-1]\),模 ...
- 模式匹配KMP算法
关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...
- kmp算法详解
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
- KMP算法——Javascript实现
腾讯和阿里的笔试刚过去了,里面有很多题都很值得玩味的.之前Blog积累的很多东西,还要平时看的书,都有很大的帮助.这个深有体会啊! 例如,腾讯有一道算法题是吃香蕉(好邪恶的赶脚..),一次吃一根或者两 ...
- 字符串匹配之KMP算法
KMP算法使用前缀函数来模拟有限自动机的后缀函数,前缀函数通过计算模式与其自身的偏移匹配的信息,本身的证明很复杂,关键在于弄懂其核心思想,下面就不赘述了,仅仅贴出代码: #include <io ...
随机推荐
- Java权限管理(授权与认证)
CRM权限管理 有兴趣的同学也可以阅读我最近分享的:Shiro框架原理分析 (PS : 这篇博客里面介绍了使用Shiro框架的方式实现权限管理) https://www.cnblogs.com/y ...
- 利用端口转发来访问virtualbox虚拟机centos6的jupyter notebook
1.除了在virtualbox中设置常规的端口转发外,还需要在windows上打开cmd,输入ssh -N -f -L localhost:8888:localhost:8889 -p 22 root ...
- node assert.equal()
浅测试,使用等于比较运算符(==)来比较 actual 和 expected 参数. const assert = require('assert'); assert.equal(1, 1); // ...
- leetcode-240搜索二维矩阵II
搜索二维矩阵II class Solution: def searchMatrix(self, matrix, target): """ :type matrix: Li ...
- Java Class 利用classpath来获取源文件地址
利用classpath来获取源文件地址 @author ixenos 应用场景 Properties props = new Properties(); /** * . 代表java命令运行的目录 * ...
- CF-697B Barnicle与691C Exponential notation
无聊写两个题解吧,上午做比赛拉的,感触很多! B. Barnicle time limit per test 1 second memory limit per test 256 megabytes ...
- HDU 2897 经典巴什博弈
从n个石子中每次取p~q个,求先手能否获胜 可以先列举一部分数据,然后观察可得总是在p+q中循环,所以只要用n对p+q取模就好了 #include <cstdio> #include &l ...
- 【ZJOI2017 Round1练习】D7T1 graph(提答)
题意: n<=1000 m<=10000 思路:
- cogs——2416. [HZOI 2016]公路修建
2416. [HZOI 2016]公路修建 ★☆ 输入文件:hzoi_road.in 输出文件:hzoi_road.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述 ...
- 浅识MySQL
MySQL常用语句 #操作数据库 ##创建数据库 CREATE DATABASE `dbName`; ##切换数据库 USE `dbName`; ##查看所有数据库 SHOW DATABASES; # ...