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

news2024/11/13 4:15:27

[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.coloradmin.cn/o/709545.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CMake 变量

目录 cmake普通变量 如何取消变量 cmake环境变量 cmake缓存变量 普通变量使用: 缓存变量使用: cmake变量的作用域 block() block demo: function 函数作用域简单 demo 高级变量 总结: 和其他语言一样,cmake完全可以看做是一种编程语言,他有变量,有函数等. cmake普通…

解决uview-plus组件样式修改不生效

一、问题描述 使用 ::v-deep 、/deep/ 等各种 deep 写法后&#xff0c;修改 uview-plus组件样式依旧不生效 二、解决方案 在子组件中写页面布局&#xff0c;在父组件中写CSS样式 目录结构&#xff1a; 父组件中&#xff1a;引入子组件&#xff0c;使用::v-deep修改样式 子组件…

git配置密钥及提交代码到仓库

原文合集地址如下&#xff0c;有需要的朋友可以关注 本文地址 合集地址 一、git下载及安装 Git官网&#xff1a;www.git-scm.com/ 下载安装包进行安装。 点击downloads下载自己需要的安装包。本文基于windows系统。 下载安装包后双击exe文件&#xff0c;如何一系列next操作…

提升文件管理效率:轻松批量归类文件,按名称细分管理

现代生活中&#xff0c;我们每天都面对着大量的电子文件&#xff0c;如文档、照片、音乐和视频等。这么多文件堆积在一起&#xff0c;怎样快速找到需要的文件成了一个挑战。现在有应该方法可以帮助您提升文件管理效率&#xff0c;方法如下&#xff1a; 首先&#xff0c;第一步…

AutoSAR系列讲解(入门篇)4.6-BSW的Watchdog功能

一、架构与术语解释 前面都挺难的吧&#xff1f;实践出真知&#xff0c;后面实践篇的时候&#xff0c;大家应该就能明白了。这一节就来讲个简单的功能------看门狗。看门狗想必大家应该都再熟悉不过了吧&#xff0c;主要就下面三层结构&#xff0c;简单明了&#xff0c;这节确实…

从入门到精通:解锁Linux开发工具和编译器的力量

目录 一.编辑器vim的使用1.vim的基本概念2.vim的使用二.编译器gcc/g1.编译器的使用2.编译器是如何完成的&#xff1f;3.动态库与静态库 一.编辑器vim的使用 1.vim的基本概念 vim是一个方便编程的功能特别丰富的文本编辑器&#xff0c;凭借他简洁的三种模式以及丰富的快捷键操…

Arduino IDE的安装

https://www.arduino.cc/en/software/

AI 绘画 - 建筑绘图辅助设计之 Controlnet

前情提要 2023-06-17 周六 杭州 阴 小记: 早上还是可以听到淅淅沥沥的雨声&#xff0c;或许梅雨季快要来了&#xff0c;潮湿的感觉说不上多讨厌&#xff0c;可是也没有那么喜欢&#xff1b;最近在追动画《飞出个未来》&#xff0c;我是把这个动画当作哲学课来看的&#xff0c…

linux模块的变量与函数导出与引用

在Linux内核中&#xff0c;不同模块之间可以通过导出和引用函数或变量的方式来进行交互。具体而言&#xff0c;Linux内核提供了一些导出和引用符号的机制&#xff0c;这些机制可以使得不同模块之间能够访问并使用彼此的函数或变量。 导出符号的方式一般有两种&#xff1a; 使…

【动态规划算法练习】day12

文章目录 一、978. 最长湍流子数组1.题目简介2.解题思路3.代码4.运行结果 二、413. 等差数列划分1.题目简介2.解题思路3.代码4.运行结果 三、1567. 乘积为正数的最长子数组长度1.题目简介2.解题思路3.代码4.运行结果 总结 一、978. 最长湍流子数组 1.题目简介 978. 最长湍流子…

python输出颜色(终端控制台)

python输出颜色&#xff08;终端控制台&#xff09; 1、终端ANSI2、Python自带的函数库ctypes3、colorama 1、终端ANSI 更多查看 ECHOX.bat输出文本背景和文字颜色 其中特殊字符print("Black :[30m f0 [0m Black :[40m b0 [0m")即是print("Black :\033[30m f0 …

3.设计模式之后七种模式桥接装饰者组合外观享元代理模板

1.桥接模式 bridge(抽象类的实现的子类,通过聚合间接调用接口方法 就是桥) 实现和抽象分开,使他可以独立改变结构型设计模式基于类的最小设计原则(增加功能,增加最少个数的类),通过封装 聚合和继承让不同类实现不同职责 图 23桥接模式原理图 图 26桥接模式传统解决手机操作问题…

(六)Spring源码解析:Spring AOP源码解析

〇、AOP概念 Aspect&#xff1a;切面 给业务方法增加到功能&#xff0c;切面泛指交叉业务逻辑。上例中的事务处理、日志处理就可以理解为切面。常用的切面是通知&#xff08;Advice&#xff09;。实际就是对主业务逻辑的一种增强。 Pointcut&#xff1a;切入点 切入点指声明的…

Nerf-Wild神经辐射场论文学习笔记 Neural Radiance Fields for Unconstrained Photo Collections

前言&#xff1a; 本文为记录自己在Nerf学习道路的一些笔记&#xff0c;包括对论文以及其代码的思考内容。公众号&#xff1a; AI知识物语 B站讲解&#xff1a;出门吃三碗饭 本篇文章主要针对其数学公式来学习其内容&#xff0c;欢迎批评指正&#xff01;&#xff01;&#x…

10-C++学习笔记-字符串

&#x1f4da; 前言 字符串是在编程中广泛使用的数据类型&#xff0c;用于表示一系列字符。在C中&#xff0c;我们可以使用C风格字符串和string类来处理字符串操作。本篇学习笔记将详细介绍字符串的相关知识。 &#x1f4d6; 1 C风格字符串 ✨ C风格字符串初始化 C风格字符…

什么是EMC存储 Clarrion存储的cache dirty或者cache lost(CACD)?

CACD是Cant assign, Cache Dirty的缩写&#xff0c;DELL EMC的专业术语。 在开始之前&#xff0c;先介绍下cache dirty的概念&#xff0c;朴素的语言就是有了脏数据&#xff0c;脏数据当然就是不能使用的数据了。为什么数据会脏呢&#xff1f;先从存储的基本概念聊起来。 为了加…

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

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

各类农作物分布遥感监测数据大全

最近收集整理了大量的农作物分布的遥感监测数据&#xff0c;废话不多说&#xff0c;分享给大家&#xff0c;后面会持续更新&#xff01;&#xff01; 数据查看地址&#xff1a; https://www.dilitanxianjia.com/%e9%81%a5%e6%84%9f%e8%a7%a3%e8%af%91%e5%90%8e%e6%88%90%e6%9…

LeetCode 0002. 两数相加

【LetMeFly】2.两数相加 力扣题目链接&#xff1a;https://leetcode.cn/problems/add-two-numbers/ 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff…