KMP解决最小循环节问题
# 10035. 「一本通 2.1 练习 1」Power Strings
【题目描述】
给定若干个长度 $\le 10^6$ 的字符串,询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如:ababab 则最多有 333 个 ab 连接而成。
【算法】
1、kmp第一步求出字符串的特征向量。若n%(n-nxt[n])==0&&nxt[n](n是字符串长度)则循环节个数为n/(n-nxt[n]),更一般地对每一个位置 $i$ 若n%(n-nxt[n])==0&&nxt[n],则前i个字符循环。
2、也可以用字符串hash,枚举循环节长度 $l$ + $O(1)$ 判定。
【代码】
#include <bits/stdc++.h>
using namespace std;
int nxt[1000100];
char s[1000100];
int main() {
while(~scanf("%s",s+1)&&s[1]!='.') {
int n=strlen(s+1);
nxt[1]=0;
for(int i=2,j=0;i<=n;i++) {
while(j>0&&(j==n||s[i]!=s[j+1])) j=nxt[j];
if(s[i]==s[j+1]) j++;
nxt[i]=j;
}
if(n%(n-nxt[n])==0&&nxt[n]) printf("%d\n",n/(n-nxt[n]));
else puts("1");
}
return 0;
}
# 10045. 「一本通 2.2 练习 1」Radio Transmission
【题目描述】
给你一个字符串,它是由某个字符串不断自我连接形成的。但是这个字符串是不确定的,现在只想知道它的最短长度是多少。
【算法】
由于该字符串可能不完全,考虑若非循环串我们将其补全,由于是最小循环节,显然,当前串最后一个字符必然位于最后一个循环节内。同时最后一个字符在匹配串和主串中和补全的最后一个字符相对位置不变,于是 $n-nxt[n]$ 也即最小循环节长度。
【代码】
#include <bits/stdc++.h>
using namespace std;
int n;
int nxt[1000100];
char s[1000100];
int main() {
scanf("%d%s",&n,s+1);
nxt[1]=0;
for(int i=2,j=0;i<=n;i++) {
while(j>0&&(j==n||s[i]!=s[j+1])) j=nxt[j];
if(s[i]==s[j+1]) j++;
nxt[i]=j;
}
int val;
for(int k=nxt[n];k;k=nxt[k])
if(k) val=n-k;
if(n%val) printf("%d\n",n/val+1);
else printf("%d\n",n/val);
return 0;
}
# 10046. 「一本通 2.2 练习 2」OKR-Periods of Words
【题目描述】
串是有限个小写字符的序列,特别的,一个空序列也可以是一个串。一个串 P 是串 A 的前缀,当且仅当存在串 B,使得 A = PB。如果 P≠A 并且 P 不是一个空串,那么我们说 P 是 A 的一个 proper 前缀。
定义 Q 是 A 的周期,当且仅当 Q 是 A 的一个 proper 前缀并且 A 是 QQ 的前缀(不一定要是 proper 前缀)。比如串 abab 和 ababab 都是串 abababa 的周期。串 A 的最大周期就是它最长的一个周期或者是一个空串(当 A 没有周期的时候),比如说,ababab 的最大周期是 abab。串 abc 的最大周期是空串。
给出一个串,求出它所有前缀的最大周期长度之和。
【算法】
这道题要求最大周期也就是循环节长度的最大值(原长不算,因为原长非周期)。于是我们考虑因为 $nxt[i]$ 数组记录的是离 i 最近的所能匹配的模式串位置,于是只要找到离 i 最远的能匹配的模式串位置即可。要么先计算出 $nxt[i]=j$ 的值,然后沿nxt数组一直找下去,直到为0的前一个,但是这样会T。于是我们再开一个数组f,记录离 i 最远的所能匹配的模式串位置,可以递推若 $f[j]>0则f[i]=j否则f[i]=j$。
【代码】
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n;
ll ans;
int nxt[1000100],f[1000100];
char s[1000100];
int main() {
scanf("%d%s",&n,s+1);
nxt[1]=0;
for(int i=2,j=0;i<=n;i++) {
while(j>0&&(j==n||s[i]!=s[j+1])) j=nxt[j];
if(s[i]==s[j+1]) j++;
nxt[i]=j;
if(f[j]>0) f[i]=f[j];
else f[i]=j;
if(f[i]) {
int len=i-f[i];
if(i%len==0) ans+=(i/len-1)*len;
else ans+=i/len*len;
}
}
printf("%lld\n",ans);
return 0;
}
KMP解决最小循环节问题的更多相关文章
- [KMP求最小循环节][HDU1358][Period]
题意 求所有循环次数大于1的前缀 的最大循环次数和前缀位置 解法 直接用KMP求最小循环节 当满足i%(i-next[i])&&next[i]!=0 前缀循环次数大于1 最小循环节是i ...
- [KMP求最小循环节][HDU3746][Cyclic Nacklace]
题意 给你个字符串,问在字符串末尾还要添加几个字符,使得字符串循环2次以上. 解法 无论这个串是不是循环串 i-next[i] 都能求出它的最小循环节 代码: /* 思路:kmp+字符串的最小循环节问 ...
- KMP + 求最小循环节 --- POJ 2406 Power Strings
Power Strings Problem's Link: http://poj.org/problem?id=2406 Mean: 给你一个字符串,让你求这个字符串最多能够被表示成最小循环节重复多少 ...
- HDU 3746 (KMP求最小循环节) Cyclic Nacklace
题意: 给出一个字符串,要求在后面添加最少的字符是的新串是循环的,且至少有两个循环节.输出最少需要添加字符的个数. 分析: 假设所给字符串为p[0...l-1],其长度为l 有这样一个结论: 这个串的 ...
- KMP + 求最小循环节 --- HUST 1010 - The Minimum Length
The Minimum Length Problem's Link: http://acm.hust.edu.cn/problem/show/1010 Mean: 给你一个字符串,求这个字符串的最小循 ...
- 模板题 + KMP + 求最小循环节 --- HDU 3746 Cyclic Nacklace
Cyclic Nacklace Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=3746 Mean: 给你一个字符串,让你在后面加尽 ...
- KMP + 求最小循环节 --- HDU 1358 Period
Period Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=1358 Mean: 给你一个字符串,让你从第二个字符开始判断当前长度 ...
- KMP解决字符串最小循环节相关问题
经典问题 : 给出一个由某个循环节构成的字符串,要你找出最小的循环节,例如 abababab 最小循环节当是 ab ,而类似 abab 也可以成为它的循环节,但并非最短. 分析 : 对于上述问题有两个 ...
- POJ2406Power Strings (最小循环节)(KMP||后缀数组)
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc&quo ...
随机推荐
- IDEA如何将git下来的是工程转为maven工程
1.在工程名称上右击并点击[Add Framework Support] 2.在打开的[Add Framework Support]窗口中在左侧栏找到[Maven]选项并勾上并点击[OK]按钮.
- sublime安装完插件后出现的一些问题
1.安装anaconda后代码前面出现小方框 解决办法:这是由于不符合PEP8代码规范,在空白地方右击,选择anaconda --> autoformat PEP8 Errors ,同时保证导入 ...
- sh_03_第1个函数
sh_03_第1个函数 # 注意:定义好函数之后,之表示这个函数封装了一段代码而已 # 如果不主动调用函数,函数是不会主动执行的 def say_hello(): print("hello ...
- 【Leetcode】二叉树的层次遍历
题目: 给定一个二叉树,返回其节点值自底向上的层次遍历. (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 思路:采用宽度优先搜索. 时间复杂度:O(n).n为节点的数量,遍历所有节 ...
- 【spring boot 学习笔记】日志相关
1. 如何启用日志? maven依赖中添加:spring-boot-starter-logging <dependency> <groupId>org.springframew ...
- sqli-labs(10)
基于双引号的时间盲注 先来随便测试一下 发现 错不错都是返回的真确的结果 那么应该是被从定向了 我们可以输入 and sleep(5) %23 测试 加’发现立刻返回 加双引号发现报错了 过了5秒才返 ...
- Yii2.0简单隐藏index.php文件和模块配置和layout布局配置禁用和日志写入配置
隐藏index.php文件 目的:想去掉浏览器地址栏中的 index.php?r= 这一块. 在/config/web.php中 ’components'=>[] 中添加如下代码: 'u ...
- 深入浅出mysql笔记---1、mysql下载安装
深入浅出mysql笔记---1.mysql下载安装 一.总结 一句话总结: linux下rpm安装即可 1.linux的wget命令作用? 下载文件的工具:比如wget http://cn.wordp ...
- .Net Core-3.0-新闻:宣告推出.NET Core 3.0 Preview 7
ylbtech-.Net Core-3.0-新闻:宣告推出.NET Core 3.0 Preview 7 1.返回顶部 1. 今天,我们宣布推出.NET Core 3.0 Preview 7.我们已 ...
- python学习笔记:(三)list(列表)常用的内置方法
list(列表)包含一些内置的方法,以下为详细介绍: (方法调用:对象.方法(参数)) 1.append() 在列表的末尾添加新的对象 如: lst=[1,2,3] lst.append(4) --- ...