洛谷 P8368 [LNOI2022] 串 题解

news/2024/5/5 7:53:07/文章来源:https://blog.csdn.net/glorious_dream/article/details/126973885

首先感谢 高一零起点 AuAuAu 的学长 对本蒟蒻的细心教导。stostosto windwindwind_whisperwhisperwhisper orzorzorz

题目传送门

题意分析

给定一个英文小写字母构成的字符串 SSS,找到一个尽可能长的字符串序列(T0,T1,…,Tl)(T_0,T_1,\dots,T_l)(T0,T1,,Tl),满足:

  • T0T_0T0SSS 的子串;
  • ∀1≤i≤l\forall 1 \leq i \leq l∀1il∣Ti∣−∣Ti−1∣=1\mid T_i \mid - \mid T_{i-1} \mid = 1TiTi1∣=1
  • ∀1≤i≤l\forall 1 \leq i \leq l∀1il,存在 SSS 的一个长度为 ∣Ti∣+1\mid T_i \mid + 1Ti+1 的子串 Si′S'_iSi,使得 Si′S'_iSi 的长度为 ∣Ti−1∣\mid T_{i-1} \midTi1 的前缀为 Ti−1T_{i-1}Ti1,长度为 ∣Ti∣\mid T_i \midTi 的后缀为 TiT_iTi

输出这样的字符串序列的长度最大值(((lll 的最大值)))

算法分析

俗话说,正难则反。我们逆向来想如何构造可行的字符串。那么可以按如下方法构造:[i,j]→[i−1,j−2]→[i−2,j−4]→…[i,j] \rightarrow [i-1,j-2] \rightarrow [i-2,j-4] \rightarrow \dots[i,j][i1,j2][i2,j4] 一直这样下去,直到长度为 000 或者到头了。那么答案有一个最小值是 ⌊n/2⌋\lfloor n/2 \rfloorn/2

用下面的图能很好的说明为什么这么构造是合法的。
在这里插入图片描述
由于题目中说一个是前缀,一个是后缀,那么这么构造就行。接下来的 Ti−2T_{i-2}Ti2 与这种构造方法相同。
在这里插入图片描述
解决完合法性,我们考虑如何统计答案。上文中说到,答案有一个下界是 ⌊n/2⌋\lfloor n/2 \rfloorn/2,这种情况是一直往前跳,跳到空串为止。那么有没有情况是可以更新这个答案的呢?有!看下面这张图。
在这里插入图片描述
字符串 Ti−1T_{i-1}Ti1 在大串 SSS 中出现了两次,那么我们在从 TiT_iTi 跳到 Ti−1T_{i-1}Ti1 的时候,可以跳到后面那个 Ti−1T_{i-1}Ti1,这样的话当跳到前面那个 Ti−1T_{i-1}Ti1 的时候,我们就可以跳回到后面的 Ti−1T_{i-1}Ti1。那么对于出现次数 ≥2\geq 22 的串 [l,r][l,r][l,r],选择从它开始跳,答案为 r−l+1+⌊(n−r)/2⌋r-l+1+\lfloor (n-r)/2 \rfloorrl+1+⌊(nr)/2。我们求出以每个下标为右端点的最长的出现次数 ≥2\geq 22的串,取个 max⁡\maxmax,然后再和答案下界 ⌊n/2⌋\lfloor n/2 \rfloorn/2 取个 max⁡\maxmax 即可。

总代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#define re register
#define drep(a,b,c) for(re int a(b) ; a>=(c) ; --a)
#define rep(a,b,c) 	for(re int a(b) ; a<=(c) ; ++a)
using namespace std;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;
}
inline void print(int x){if(x < 0) putchar('-'),x = -x;if(x >= 10) print(x / 10);putchar(x % 10 + '0');
}
const int M = 1e6+100;
int ch[M][26],len[M],fa[M],head[M],siz[M],pos[M];
char s[M];
int T,n,cnt,ans,tot=1,np=1;
struct edge{int to,nxt;
}e[M];
inline void add(int u,int v){e[++cnt].to = v;e[cnt].nxt = head[u];head[u] = cnt;
}
inline void init(){rep(i,1,tot){memset(ch[i],0,sizeof(ch[i]));head[i] = 0;siz[i] = 0;}cnt = ans = 0;tot = np = 1;
}
inline void sam_extend(int c,int id){int p = np; np = ++tot;len[np] = len[p] + 1;siz[np] = 1;pos[np] = id;for( ; p && !ch[p][c] ; p = fa[p]) ch[p][c] = np;if(p == 0) fa[np] = 1;else{int q = ch[p][c];if(len[q] == len[p] + 1) fa[np] = q;else{int nq = ++tot;fa[nq] = fa[q]; fa[q] = nq; fa[np] = nq;len[nq] = len[p] + 1;pos[nq] = n+1;siz[nq] = 0;for( ; p && ch[p][c]==q ; p = fa[p]) ch[p][c] = nq;memcpy(ch[nq],ch[q],sizeof(ch[nq]));}}
}
inline void dfs(int u){for(re int i(head[u]) ; i ; i=e[i].nxt){int v = e[i].to;dfs(v);siz[u] += siz[v];pos[u] = min(pos[u],pos[v]);}if(siz[u] > 1) ans = max(ans,len[u]+(n-pos[u])/2);
}
inline void work(){init();scanf("%s",s+1);n = strlen(s+1);rep(i,1,n) sam_extend(s[i]-'a',i);rep(i,2,tot) add(fa[i],i);ans = n/2;dfs(1);printf("%d\n",ans);
}
signed main(){T = read();while(T--) work();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_11480.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【力扣】杨辉三角问题

力扣&#xff5c;杨辉三角【力扣】杨辉三角I✌杨辉三角快速入门&#x1f4ac;输出杨辉三角I问题&#x1f375;思路分析✍️ 算法实现【力扣】杨辉三角II&#x1f4ac; 输出杨辉三角II问题&#x1f375;思路分析✍️ 算法实现【力扣】杨辉三角I ✌杨辉三角快速入门 每行端点与…

【JavaScript 逆向】猿人学 web 第十八题:jsvmp,洞察先机

案例目标 网址&#xff1a;第十八题 jsvmp 洞察先机 - 猿人学 本题目标&#xff1a;抓取 5 页数字&#xff0c;计算加和并提交结果 常规 JavaScript 逆向思路 一般情况下&#xff0c;JavaScript 逆向分为三步&#xff1a; 寻找入口&#xff1a;逆向在大部分情况下就是找一些…

【Redis】arm64架构,docker的Redis出现Failed to test the kernel for a bug that could lead to data corruption

一、问题说明在运行docker的redis镜像,log打印 # Failed to test the kernel for a bug that could lead to data corruption during background save. Your system could be affected, please report this error.# Redis will now exit to prevent data corruption. Note tha…

Replication(下):事务,一致性与共识

本文主要介绍事务、一致性以及共识&#xff0c;首先会介绍它们怎么在分布式系统中起作用&#xff0c;然后将尝试描述它们之间的内在联系&#xff0c;让大家了解&#xff0c;在设计分布式系统时也是有一定的“套路”可寻。最后将介绍业界验证分布式算法的一些工具和框架。希望能…

告别if else,试试这款轻量级流程引擎吧,自带IDEA插件真香

在我们平时做项目的时候&#xff0c;经常会遇到复杂的业务逻辑&#xff0c;如果使用if else来实现的话&#xff0c;往往会很冗长&#xff0c;维护成本也很高。今天给大家推荐一个轻量级流程引擎 LiteFlow &#xff0c;可以优雅地实现复杂的业务逻辑&#xff0c;本文将以电商项目…

HashSet的存储机制

文章目录HashSet类内部存储机制实验1.不重写hashcode equals方法2.重写&#xff0c;但改写equals3.重写参考&#xff1a;HashSet类 HashSet是Set接口的典型实现&#xff0c;大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素&#xff0c;因此具…

PID控制算法

闭环控制(反馈回路close loop): 闭环控制系统需要目标量,执行器,传感器 通过偏差量获得执行量是最为重要的 目标量和传感器获得的执行器数据都需要是连续的; 偏差量来自于传感器和目标量数据和执行量不是同一个单位,需要一个比例P系数进行规整; 偏差量=目标量-当前位置量…

Java项目:JSP宠物店管理系统

作者主页&#xff1a;夜未央5788 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;主要分为管理员与用户两种角色&#xff0c;管理员登录后台&#xff0c;普通用户登录前台&#xff1b; 管理员角色包含…

【LeetCode每日一题】——面试题17.16.按摩师

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 动态规划 二【题目难度】 简单 三【题目编号】 面试题17.16.按摩师 四【题目描述】 一个有名的按摩师会收到…

App移动端测试(10)—— Monkey自定义脚本案例

01、前言 Monkey自定义脚本案例&#xff1a;QQ的操作 02、Monkey API LaunchActivity(pkg_name, cl_name)启动应用的Activity。参数&#xff1a;包名和启动的 Tap(x, y, tapDuration)模拟一次手指单击事件。参数&#xff1a;x,y为控件坐标&#xff0c;tapDuration为点击的持续…

你到底是前端人还是搬砖人?推荐一款国产摸鱼神器!

☀️ 前言 大家好我是小卢&#xff0c;前几天在群里见到有群友抱怨一周内要完成这么一个大概20&#xff5e;30页的小程序。 群友: 这20多个页面一个星期让我开发完&#xff0c;我是不相信&#x1f62e;‍&#x1f4a8;。群友1: 跑吧&#xff0c;这公司留着没用了&#xff0c;不…

【Python 技能树共建】Beautiful Soup

Beautiful Soup 模块是什么 初学 Python 爬虫&#xff0c;十之八九你采集的目标是网页&#xff0c;因此快速定位到网页内容&#xff0c;就成为你面临的第一道障碍&#xff0c;本篇博客就为你详细说明最易上手的网页元素定位术&#xff0c;学完就会系列。 本文核心使用到的是 …

Spring Security 中的RBAC角色和权限

在这篇文章中&#xff0c;我们将看看使用 Spring boot的R ole B ased A ccess Control ( RBAC )。 了解 RBAC 在 RBAC 模型中存在三个关键实体。他们是&#xff0c; 用户或主题 ——执行操作的系统参与者。它可以代表一个自然人、一个自动帐户&#xff0c;甚至是另一个应用程…

专业思维导图软件 Mindjet MindManager 2021下载

Mindjet MindManager 2021 是一款专业的思维导图软件&#xff0c;美国Mindjet公司开发&#xff0c;一款视觉工作管理的思维导图软件&#xff0c;界面友好功能强大&#xff0c;头脑风暴、会议管理及项目管理工具帮您轻松创建思维导图&#xff0c;有序组织思维、资源和项目进程。…

win10+cuda+cudnn+anconda+pytorch+pycharm全家桶安装

1、下载安装cuda&#xff1a; 网址&#xff1a;CUDA Toolkit 11.7 Update 1 Downloads | NVIDIA Developer 网址下方可以找到以前版本 安装完后&#xff0c;可以在命令行窗口输入nvcc --version查看cuda版本是否正确 显卡驱动版本与cuda版本对应关系&#xff1a; 2、安装cud…

操作系统实验四 进程间通信

★观前提示&#xff1a;本篇内容为操作系统实验内容&#xff0c;代码等内容经测试没有问题&#xff0c;但是可能会不符合每个人实验的要求&#xff0c;因此以下内容建议仅做思路参考。 目录一、实验目的二、实验内容三、具体实现四、实验总结一、实验目的 多道程序设计中&…

【前端面试】-- 必知必会的promise题

Promise 想必大家都十分熟悉&#xff0c;想想就那么几个 api&#xff0c;可是你真的了解 Promise 吗&#xff1f; 请迎接测试: 以下 promise 均指代 Promise 实例&#xff0c;环境是 Node.js 题目一&#xff1a; const promise new Promise((resolve, reject) > {conso…

ES8JC-ASEMI快恢复二极管ES8JC

编辑:ll ES8JC-ASEMI快恢复二极管ES8JC 型号:ES8JC 品牌:ASEMI 封装:SMC 特性:快恢复二极管 正向电流:8A 反向耐压:600V 恢复时间:35ns 引脚数量:2 芯片个数:1 芯片尺寸:84MIL 浪涌电流:125A 漏电流:<5ua 工作温度:-40℃~150℃ 包装方式:30/管;3000/箱 备受…

华为云各Region网络延迟实测

一、测试综述 测试内容&#xff1a; 序号 评测内容 测试日期 1 华为云各大区公网接入网络延迟 2022-09-20 2 华为云各大区之间网络延迟&#xff08;通过公网&#xff09; 2022-09-20 3 华为云各大区之间网络延迟&#xff08;通过云连接&#xff09; 2022-09-20 测…

【Linux】聊聊删文件的那些破事

聊聊删文件的那些破事前言正文rm命令find命令perl方式10w文件删除对比50w文件删除对比100w文件删除对比结语前言 在操作系统的日常运维中&#xff0c;我们经常会做文件的创建、删除、修改操作&#xff0c;尤其是删除&#xff0c;无论是定期清理日志文件&#xff0c;还是做完一…