当前位置: 首页 > news >正文

[POI2006] OKR-Periods of Words——最大周期长度(扩展最小周期长度)

[POI2006] OKR-Periods of Words——最大周期长度(扩展最小周期长度)

[原题链接](P3435 [POI2006] OKR-Periods of Words - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))


字符串的周期

讲这道题之前,我们先聊一聊字符串的周期。我们要明确周期border两个概念

周期

对字符串 s s s 0 < p ≤ ∣ s ∣ 0<p\leq \left|s \right| 0<ps,若 s [ i ] = s [ i + p ] s[i]=s[i+p] s[i]=s[i+p]对所有 i ∈ [ 0 , ≤ ∣ s ∣ − p − 1 ] i \in [0,\leq \left|s \right| -p-1] i[0,sp1] 成立,则称 p p p s s s的周期

border

对字符串 s s s 0 < p < ∣ s ∣ 0<p< \left|s \right| 0<p<s,若s长度为r的前缀和长度为r的后缀相等,就称s长度为r的前缀是s的border

由s由长度为r的border可以推导出 ≤ ∣ s ∣ − r \leq \left|s \right|-r sr是s的周期

根据kmp的next数组,可以得到s(下标从0开始)的所有border长度,next[n-1],next[next[n-1]-1],…

显然s的最小周期 n − n e x t [ n − 1 ] n-next[n-1] nnext[n1]

思路

现在我们回到该题:

该题就是让我们求字符串 s 1 s_1 s1的最小周期

代码

代码如下

#include <bits/stdc++.h>using namespace std;const int N = 1e6 + 10;char c[N];
int ne[N];int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int n;// 字符串下标从1开始cin >> n >> c + 1;// 获取next数组for (int i = 2, j = 0; i <= n; i ++) {while (j && c[i] != c[j + 1])j = ne[j];if (c[i] == c[j + 1]) {j ++;ne[i] = j;}}cout << n - ne[n];return 0;
}

扩展:最大周期长度

让每一个next数组的值都是最短前缀

核心代码

int j = n;
// 转换为最短前缀
while (ne[j]) j = ne[j];
// 记忆化存储
if (ne[i])  ne[i] = j;
// 最大周期长度
len = n - j;

例题

[[POI2006] OKR-Periods of Words](P3435 [POI2006] OKR-Periods of Words - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

分析

求每个子串的最大周期长度

样例分析

bab 2

baba 2

babab 4

bababa 4

bababab 6

babababa 6

参考代码

#include <iostream>using namespace std;const int N = 1e6 + 10;
typedef long long LL;char s[N];
LL ne[N];int main() {ios::sync_with_stdio(0);cin.tie(0);int n;cin >> n >> s + 1;for (int i = 2, j = 0; i <= n; i ++) {while (j && s[i] != s[j + 1])j = ne[j];if (s[i] == s[j+1])j ++;ne[i] = j;}LL ans = 0;for (int i = 2; i <= n; i ++) {int j = i;while (ne[j]) {j = ne[j];}if (ne[i])  ne[i] = j;ans += i-j;}cout << ans << endl;return 0;
}

相关文章:

  • could not read ok from ADB Server
  • linux生产者消费者模型
  • 大语言模型(LLM)综述(六):大型语言模型的基准和评估
  • 基于springboot+vue的影城管理系统
  • C嘎嘎之类和对象下
  • @Bean有哪些属性
  • Comparator接口与Lambda表达式
  • 回调函数——qsort的模拟实现
  • 『MySQL快速上手』-③-库的操作
  • 一、Hadoop初始化配置(final+ubuntu保姆级教程)
  • 钉钉内嵌H5遇到的一些问题
  • html中使用JQ自定义锚点偏移量
  • 价钱统计
  • 数字摄影测量
  • 换服还是掀桌?哪条才是程序员的出路?
  • JavaScript 如何正确处理 Unicode 编码问题!
  • C++入门教程(10):for 语句
  • docker python 配置
  • Flannel解读
  • HTTP传输编码增加了传输量,只为解决这一个问题 | 实用 HTTP
  • Material Design
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • PHP 使用 Swoole - TaskWorker 实现异步操作 Mysql
  • Python3爬取英雄联盟英雄皮肤大图
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 老板让我十分钟上手nx-admin
  • 力扣(LeetCode)22
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 使用Swoole加速Laravel(正式环境中)
  • 用mpvue开发微信小程序
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # Swust 12th acm 邀请赛# [ E ] 01 String [题解]
  • #define MODIFY_REG(REG, CLEARMASK, SETMASK)
  • (C#)一个最简单的链表类
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET Core 和 .NET Framework 中的 MEF2
  • .Net Core 中间件验签
  • .NET Micro Framework初体验(二)
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .Net环境下的缓存技术介绍
  • @vue/cli 3.x+引入jQuery
  • [ Linux Audio 篇 ] 音频开发入门基础知识
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • []sim300 GPRS数据收发程序