蓝书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 ...
随机推荐
- php与mysql事物处理
PHP与MYSQL事务处理 mysql事物特性 (原子性,一致性,隔离性,持久性) /*MYSQL的事务处理主要有两种方法.1.用begin,rollback,commit来实现begin 开始一个事 ...
- JavaScript中数据类型的转换规则
JavaScript中数据类型的转换规则 制作人:全心全意 JavaScript是一种无类型语言,也就是说,在声明变量时无须指定数据类型,这使得JavaScript更具有灵活性和简单性. 在代码执行过 ...
- UVA 12100 打印队列(STL deque)
题意: 给定n个优先级打印队列,然后从0开始编号到n-1.出队一个元素,如果他是队列中优先级最高的,打印(耗时一分钟),否则放到队尾(不耗时).给定一个m,求位置m的文件打印的时间. 分析: 用一个p ...
- LeetCode 121. Best Time to Buy and Sell Stock (stock problem)
Say you have an array for which the ith element is the price of a given stock on day i. If you were ...
- 表情符号Emoji的正则表达式
/** * 判断字符串包含表情 * @param value * @return */ public static boolean containsEmoji(String value){ boole ...
- LIBSVM使用方法及参数设置
LIBSVM 数据格式需要---------------------- 决策属性 条件属性a 条件属性b ... 2 1:7 2:5 ... 1 1:4 2:2 ... 数据格式转换--------- ...
- 图解使用IDEA创建第一个Java程序HelloWorld
前几次给大家分享了怎么在自己的电脑上配置 java 环境,准备工作做好了,我们就要开始我们真正的编码学习了.下面介绍使用 IDEA 创建我们的第一个 HelloWorld 程序. 1.打开 IDEA, ...
- 【转】jquery 注册事件的方法
原文链接:http://outofmemory.cn/code-snippet/2123/jquery-zhuce-event-method 1.使用事件名来绑定,可用的事件名有 change,cli ...
- ZOJ 2561 Order-Preserving Codes
Order-Preserving Codes Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on ZJU. ...
- [luoguP1043] 数字游戏(DP)
传送门 搞个前缀和随便DP一下 代码 #include <cstdio> #include <cstring> #include <iostream> #defin ...