CF1527 E2. Erase and Extend (Hard Version)
题意:
给出一个长为n的字符串,你可以进行2种操作
1、把串在后面再拼接一次
2、删去串的最后一个元素
要求用这两种操作得出字典序最小的长为m的串
首先答案肯定是由一个前缀拼接多次构成
假设当前的最优前缀是A前缀,长度为LA,现在正在考虑的是B前缀
1、如果s[B%LA]和s[A]一样,那么不用管继续往后走
2、如果s[B%LA]比s[A]小,那么B前缀比A前缀更优秀
3、如果s[B%LA]比s[A]大,那么A前缀比B前缀更优秀
先来看2和3的正确性
在1的条件下,他们都包含了s[0…A]拼接多次=s[0…B-1]
所以只需要比较s[B%LA]与s[A]即可
然后是1的正确性,它包含了s[0…A]拼接多次=s[0…B]
令B%LA=t,可以把前B的字符分为3段
s[0…t]一段记为X,s[t+1,LA-1]一段记为Y,s[LA…B]一段等同于s[0…t]
如果还是用A前缀,那么拼接结果是XYXYXYXY
如果改为用B前缀,那么拼接结果是XYXXYXXY
所以如果YX<XY,那么还是原先的A前缀
如果XY<YX,才会改用B前缀
但是如果XY<YX,XY的拼接就不会是最小的,因为X的拼接会给更小
#include<bits/stdc++.h> using namespace std; #define N 500003 char s[N]; int main() { int n,m; scanf("%d%d",&n,&m); scanf("%s",s); int len=1; for(int i=1;i<n;++i) if(s[i]<s[i%len]) len=i+1; else if(s[i]>s[i%len]) break; int now=0; for(int i=1;i<=m;++i) { printf("%c",s[now]); ++now; if(now==len) now=0; } }
分类:
其他——构造
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2020-10-04 天梯赛 球队“食物链”
2020-10-04 天梯赛 周游世界