#10046. 「一本通 2.2 练习 2」OKR-Periods of Words(内附封面)

2023/11/29 14:37:30

[POI2006] OKR-Periods of Words

题面翻译

对于一个仅含小写字母的字符串 a a a p p p a a a 的前缀且 p ≠ a p\ne a p=a,那么我们称 p p p a a a 的 proper 前缀。

规定字符串 Q Q Q(可以是空串)表示 a a a 的周期,当且仅当 Q Q Q a a a 的 proper 前缀且 a a a Q + Q Q+Q Q+Q 的前缀。

例如 ababab 的一个周期,因为 ababab 的 proper 前缀,且 ababab+ab 的前缀。

求给定字符串所有前缀的最大周期长度之和。

题目描述

A string is a finite sequence of lower-case (non-capital) letters of the English alphabet. Particularly, it may be an empty sequence, i.e. a sequence of 0 letters. By A=BC we denotes that A is a string obtained by concatenation (joining by writing one immediately after another, i.e. without any space, etc.) of the strings B and C (in this order). A string P is a prefix of the string !, if there is a string B, that A=PB. In other words, prefixes of A are the initial fragments of A. In addition, if P!=A and P is not an empty string, we say, that P is a proper prefix of A.

A string Q is a period of Q, if Q is a proper prefix of A and A is a prefix (not necessarily a proper one) of the string QQ. For example, the strings abab and ababab are both periods of the string abababa. The maximum period of a string A is the longest of its periods or the empty string, if A doesn’t have any period. For example, the maximum period of ababab is abab. The maximum period of abc is the empty string.

Task Write a programme that:

reads from the standard input the string’s length and the string itself,calculates the sum of lengths of maximum periods of all its prefixes,writes the result to the standard output.

输入格式

In the first line of the standard input there is one integer k k k ( 1 ≤ k ≤ 1   000   000 1\le k\le 1\ 000\ 000 1k1 000 000) - the length of the string. In the following line a sequence of exactly k k k lower-case letters of the English alphabet is written - the string.

输出格式

In the first and only line of the standard output your programme should write an integer - the sum of lengths of maximum periods of all prefixes of the string given in the input.

样例 #1

样例输入 #1

8
babababa

样例输出 #1

24

数据范围与提示

对于全部数据, 1 < k < 1 0 6 1\lt k\lt 10^6 1<k<106

人话翻译:

给定一个字符串A,求他所有前缀B(包括A=B)的最大周期,周期即B的前缀C最长,C要满足B是CC的字串。实例:
A B A B A B A B 的所有前缀有: − − − − − − − − − 周期为 − − − 长度 ABABABAB的所有前缀有:---------周期为---长度 ABABABAB的所有前缀有:周期为长度
A − − − − − − − − − − − − − − − − − − − − 无 − − − − − 0 A--------------------无-----0 A0
A B − − − − − − − − − − − − − − − − − − − 无 − − − − − 0 AB-------------------无-----0 AB0
A B A − − − − − − − − − − − − − − − − − − A B − − − − − 2 ABA------------------AB-----2 ABAAB2
A B A B − − − − − − − − − − − − − − − − − A B − − − − − 2 ABAB-----------------AB-----2 ABABAB2
A B A B A − − − − − − − − − − − − − − − − A B A B − − − − 4 ABABA----------------ABAB----4 ABABAABAB4
A B A B A B − − − − − − − − − − − − − − − A B A B − − − − 4 ABABAB---------------ABAB----4 ABABABABAB4
A B A B A B A − − − − − − − − − − − − − − A B A B A B − − − 6 ABABABA--------------ABABAB---6 ABABABAABABAB6
A B A B A B A B − − − − − − − − − − − − − A B A B A B − − − 6 ABABABAB-------------ABABAB---6 ABABABABABABAB6
因此输出结果为 2 + 2 + 4 + 4 + 6 + 6 = 24 因此输出结果为2+2+4+4+6+6=24 因此输出结果为2+2+4+4+6+6=24

怎么求这些周期长度呢?KMP的精髓也在此,附图(其中next数组就是之前模板中提到的p数组,含义是相同的)

在这里插入图片描述

明显其中的蓝线是黑线的周期

那么这个题目就变得极其简单了,只需要求出 i − n e x t [ n e x t [ i ] ] i-next[next[i]] inext[next[i]],ans累加即可

很简单就可以得到实现代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+999;
int p[N],n,len,ans=0;
char a[N];
void pre(){//KMP模板
	int j=0;p[1]=0;
	for(int i=1;i<n;i++){
		while(j>0&&a[i+1]!=a[j+1])j=p[j];
		if(a[i+1]==a[j+1])j++;
		p[i+1]=j;
	}
} 
int main(){
	cin>>n;
	scanf("%s",a+1);
	pre();
	for(int i=1;i<=n;i++){
		int j=i;
		while(p[j])j=p[j];
		ans+=i-j;
	}
	cout<<ans;
	return 0;
} 

但是!这样是不够的,会得到以下结果

在这里插入图片描述

算法原理是肯定没有错的,但是问题在哪?

注意k的范围

对于全部数据, 1 < k < 1 0 6 1\lt k\lt 10^6 1<k<106
那么对于我们在累加的ans可能会超出int的范围

十年OI一场空,不开long long 见祖宗

加上longlong

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+999;
int p[N],n;
long long int ans=0;
char a[N];
void pre(){
	int j=0;p[1]=0;
	for(int i=1;i<n;i++){
		while(j>0&&a[i+1]!=a[j+1])j=p[j];
		if(a[i+1]==a[j+1])j++;
		p[i+1]=j;
	}
} 
int main(){
	cin>>n;
	scanf("%s",a+1);
	pre();
	for(int i=1;i<=n;i++){
		int j=i;
		while(p[j])j=p[j];
		if(p[i]!=0)p[i]=j; 
		ans+=i-j;
	}
	cout<<ans;
	return 0;
} 

信心十足的交上代码,

在这里插入图片描述

哎?不是,啊?KMP超时了?FFFF

咳,随着数据变大,查找 n e x t [ n e x t [ ] ] next[next[]] next[next[]]的时间就变得难以接受,我们可以通过记忆化的方式更改 n e x t next next数组,原理类似于并查集的优化

实现代码(AC)

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+999;
int p[N],n;
long long int ans=0;
char a[N];
void pre(){
	int j=0;p[1]=0;
	for(int i=1;i<n;i++){
		while(j>0&&a[i+1]!=a[j+1])j=p[j];
		if(a[i+1]==a[j+1])j++;
		p[i+1]=j;
	}
} 
int main(){
	cin>>n;
	scanf("%s",a+1);
	pre();
	for(int i=1;i<=n;i++){
		int j=i;
		while(p[j])j=p[j];
		if(p[i]!=0)p[i]=j;//记忆化,否则会有TLE。 
		ans+=i-j;
	}
	cout<<ans;
	return 0;
} 

附封面

请添加图片描述


http://www.jnnr.cn/a/575284.html

相关文章

Leetcode-每日一题【142.环形链表Ⅱ】

题目 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部…

帆软 FineReport 绘制漏斗图

七一建党节&#xff0c;祝党生日快乐&#xff01; 夏日炎炎&#xff0c;周末在家&#xff0c;想起在用帆软做页面展示的时候&#xff0c;使用到了漏斗图&#xff0c;记录下来&#xff0c;方便查看。 以订单销量变化为例&#xff0c;分为五个阶段&#xff0c;商品浏览人数&#…

Java基础---为什么不能用浮点数表示金额

目录 缘由 十进制转二进制 不是所有数都能用二进制表示 IEEE 754 避免精度丢失 缘由 因为不是所有的小数都能用二进制表示&#xff0c;所以&#xff0c;为了解决这个问题&#xff0c;IEEE提出了一种使用近似值表示小数的方式&#xff0c;并且引入了精度的概念这就是我们所…

Nacos 配置更新的工作流程

首先&#xff0c;Nacos 是采用长轮训的方式向 Nacos Server 端发起配置更新查询的功能。所谓长轮训&#xff0c;&#xff08;如图&#xff09;就是客户端发起一次轮训请求到服务端&#xff0c;当服务端配置没有任何变更的时候&#xff0c;这个连接一直打开。 直到服务端有配置或…

WebAPIs-DOM操作元素属性/自定义属性

Web APIs web APIs 操作页面元素做出各种效果 DOM 文档对象模型 使用js操作页面文档 BOM 浏览器对象模型 使用js操作浏览器 API 应用程序接口 接口&#xff1a;无需关心内部如何实现&#xff0c;只需要调用就可以很方便实现某些功能 作用&#xff1a;使用js提供的接口来操…

java 全局、局部异常处理详解及result结果封装

1、引入spring-boot-starter-web依赖和new-swagger依赖 <dependency><groupId>com.jjw</groupId><artifactId>new-swagger</artifactId><version>1.0-SNAPSHOT</version> </dependency> <dependency><groupId>or…

机器学习笔记 - 基于OpenCV和Vantage-point tree构建图像哈希搜索引擎

一、关于图像哈希 上一篇文章中,了解到了图像哈希是使用算法为图像分配唯一哈希值的过程。在深度学习普及之前,一些搜索引擎使用散列技术来索引图像。 言外之意目前的图像搜索引擎主要都是基于深度学习的技术,不过思路都是一样的,我们这里基于OpenCV提供的图像哈希技术构建…

PoseiSwap 将向 Zepoch 节点持有者发放新一轮空投,生态启动在即

目前&#xff0c;随着各类 Layer2 空投不断内卷&#xff0c;越来越多的用户疲于参与其中&#xff08;参与交互也很有可能难以获得空投资格&#xff09;。Nautilus Chain 作为目前模块化 Layer3 架构链&#xff0c;在初期就明确了空投计划&#xff0c;即所有上线的应用都将会拿出…

BM26 求二叉树的层序遍历

import java.util.*; public class Solution {public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {ArrayList<ArrayList<Integer> > res new ArrayList();if (root null)//如果是空&#xff0c;则直接返回空数组return res;//队列存…

英语语法学习_incomplete

在语言学中&#xff0c;自然语言的语法是说话者或作者在从句、短语和单词的构成上的一套结构约束。1 「语法」实际上有两个概念&#xff0c;一是「语法」&#xff08;也叫「文法」&#xff09;&#xff0c;二是「语法学」。 一、语法&#xff1a;客观存在的语言结构规律&#x…

C语言--消失的数字

文章目录 1.法一&#xff1a;映射法2.法二&#xff1a;异或法3.法三&#xff1a;差值法4.法四&#xff1a;排序查找 1.法一&#xff1a;映射法 时间复杂度&#xff1a;O&#xff08;N&#xff09; 空间复杂度&#xff1a;O&#xff08;N&#xff09; #include<stdio.h>…

vue 启动项目报错:TypeError: Cannot set property ‘parent‘ of undefined异常解决

场景&#xff1a;从git上面拉下来一个项目 npm i 下载完依赖以后 npm run serve 去运行项目的时候 报错TypeError: Cannot set property ‘parent’ of undefined 如图所示 原因&#xff1a;首先排查发现判断得出是less解析失败导致 但是经过长时间的查询解决方案发现是因为v…

【Spring】Bean的作用域与生命周期详情:请简述Spring的执行流程并分析Bean的生命周期?

前言 我们都知道&#xff0c;Spring框架为开发人员提供了很多便捷&#xff0c;这使得开发人员能够更加专注于应用程序的核心业务逻辑&#xff0c;而不需要花费大量时间和精力在技术细节上。作为一个包含众多工具方法的IoC容器&#xff0c;存取JavaBean是其极为重要的一个环节。…

WPF 样式设计总结

文章目录 行内样式页内样式样式继承控件样式只能继承一个 局部样式窗口控件和用户控件直接的区别使用代码用户控件引用 全局样式 行内样式 我们新建一个简单的样式 <Grid><TextBox Text"我是样式" FontSize"100" /></Grid>这种属性直接…

力扣题库刷题笔记17--电话号码的字母组合

1、题目如下&#xff1a; 2、个人Python代码实现&#xff1a; 还是先记录一下思路&#xff0c;首先这种类型的题&#xff0c;需要自定义一个字典对应题目中的电话号码和数字。其次&#xff0c;个人的思路是&#xff0c;先读取字符串第一个字符&#xff08;digits[0]&#xff09…

时间序列分解 | Matlab变分模态分解(VMD)的信号分解

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列分解 | Matlab变分模态分解(VMD)的信号分解 部分源码 %--------------------

React Antd Form.List 组件嵌套多级动态增减表单 + 表单联动复制实现

Antd Form.List 组件嵌套多级动态增减表单 表单联动复制实现 一、业务需求 有一个页面的组件&#xff0c;其中一部分需要用到动态的增减 复制表单&#xff0c;然后就想起 了使用 Antd 的 Form.List 去完成这个功能。 这个功能的要求是&#xff1a; 首先是一个动态的表单&…

海尔2024嵌入式提前批——编程题

题1&#xff1a; 输入一个字符c和一个偏移k&#xff0c;要求输出偏移之后的字符&#xff0c;如果超出了范围就从头开始。 输入、输出样例&#xff1a; 输入&#xff1a;a 1 输出&#xff1a;b 输入&#xff1a;a 26 输出&#xff1a;a 输入&#xff1a;A 2 输出&#xff1a;C…

手机App弹窗的常用测试点

目录 前言&#xff1a; 弹窗的类型 弹窗的操作集合 弹窗加载和展示 弹窗的元素 弹窗的属性 弹窗的兼容性 弹窗的风险 前言&#xff1a; 在对手机应用进行测试时&#xff0c;弹窗是一个重要的测试点&#xff0c;因为它们是与用户直接进行交互的元素。 手机App弹窗是目前…

Linux:etc/group

etc/group文件中保存着系统中所有组的名称&#xff0c;以及每个组中的成员列表。 文件中的一行为一个组的信息&#xff0c;具体如下&#xff1a; 如果组口令字段为x的话&#xff0c;就还有一个etc/gshadow文件用于存放组口令。 GID用于标识一个组&#xff0c;应保证其唯一性。…
最新文章