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

【ICPC】【2021沈阳站】String Problem(Lyndon分解)

传送门:String Problem        Lyndon分解 


JB hates solving string problems. Therefore, when his friend Potato gives him a string problem to solve, he immediately gives it to you and continues playing Genshin Impact, the greatest game in the world.

You are given a string and then for each nonempty prefix, you need to find the largest substring in lexicographical order and point out the leftmost occurrence of the largest substring.


Input

The only line contains a string S (1≤∣S∣≤1e6)(1≤∣S∣≤1e6), which consists of lowercase Latin letters, a to z.


Output

Output ∣S∣ lines, the i-th of which contains two integers li​ and ri​, indicating the leftmost occurrence of the largest substring in the prefix of length i.


题目大意

JB讨厌解决字符串问题。因此,当他的朋友土豆给他一个字符串问题要解决时,他会立即把它给你,并继续玩Genshin Impact,世界上最伟大的游戏。

给定一个字符串,然后对于每个非空前缀,您需要按照字典顺序找到最大的子串,并指出最大子串的最左边位置。

例如对于样例1的第二个位置'o',依题目要求有两个字串“po"和"o",字典序更大的是"po",则该子串的范围为[1,2]因此输出其左右边界1,2.

总结:题目要求处理一个字符串 S,并对于每一个非空前缀,找出该前缀中按字典序排列的最大子字符串,并指出这个最大子字符串的左、右区间的位置。


题解

发现这道题很像Lyndon分解的形式,但是题目要求的是求出所有前缀中的最大子字符串。所以考虑Lyndon的逆用,就是只改变求Lyndon分解串中的比较过程,把大于变成小于,小于变成大于即可。

下面是代码详解。

  1. 输入处理:程序首先从标准输入中读取一个字符串 S,并计算该字符串的长度 n

  2. 初始化:定义一个整型数组 ans,大小为 n,用于存储每个字符的最小划分长度。数组的初始值为 0,表示尚未被赋值。

  3. Duval 算法

    • 算法通过两个指针 i 和 k 来遍历字符串。i 表示当前处理的起始位置,j 是一个辅助变量,用于标记字符串的基本重复段。
    • 从 i 开始向后扫描,找到所有和 s[i] (当前字符) 相关的字符,以确定它们是否属于同一个划分。
    • 每当找到一个字符与 s[j] 相等,且没有被赋值 ans[k],就将其赋值为 i + 1,即当前划分的起始位置。
    • 如果发现 s[k] < s[j],则表示出现了新的小字母,更新 j 到 i,然后增加 j
    • 最后,通过一个循环while(i <= j)来更新 i,使其跳过已处理的部分。
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
char S[(int)1e6+5];
vector<int>gap;
int ans[(int)1e6+5];
void Duval(char *s,int n){
    for(int i=0,j,k;i<n;){
        if(!ans[i])ans[i]=i+1;
        for(j=i,k=i+1;k<n&&s[k]<=s[j];k++){
            if(!ans[k])ans[k]=i+1;
            if(s[k]<s[j])j=i;
            else ++j;
        }
        while(i<=j){
            i+=k-j;
        }
    }
}
int main(){
    scanf("%s",S);
    int n=strlen(S);
    Duval(S,n);
    for(int i=0;i<n;i++){
        cout<<ans[i]<<" "<<i+1<<endl;
    }
    return 0;
}

 

http://www.dtcms.com/a/32080.html

相关文章:

  • linux串口通讯
  • 周末总结(2024/02/22)
  • SpringBoot+SseEmitter实现SSE实时推送
  • 【c语言】函数_作业详解
  • 代码随想录_回溯
  • 代码编译(词法义)
  • Ansible 学习笔记
  • 如果后台的Long类型的数据返回是null,那么Android客户端的数据bean的kotlin的Long类型的字段接受到数据后是null空指针吗?
  • 用scratch制作一个简易计算器
  • 【Linux】35.封装 UdpSocket(2)
  • Coroutine协程
  • MySQL要点总结一
  • #渗透测试#批量漏洞挖掘#Progress Software Flowmon命令执行漏洞(CVE-2024-2389)
  • HarmonyOS 开发套件 介绍——下篇
  • 代码随想录算法训练营day42(0210)
  • 《平面几何强化训练题集》第2章10-29题
  • web服务器信创,保兰德(ESB)实时步骤
  • 2025软件测试面试常问的题(详细解析)
  • 在一个集成的 SynMatrix-Ansys 设计工作流程中实现 3D 滤波器仿真
  • 从零开始用react + tailwindcs + express + mongodb实现一个聊天程序(一)
  • 给出方法步骤 挑战解决 用加密和访问控制保护数据隐私。 调架构、参数与用 GPU 加速优化模型性能。 全面测试解决兼容性问题。
  • 本地化部署 DeepSeek:从零到一的完整指南
  • 【Java】单例模式
  • 二级公共基础之数据结构与算法篇(七)排序技术
  • 基于ffmpeg+openGL ES实现的视频编辑工具-添加贴纸(八)
  • DeepSeek R1本地+私有云版医疗AI部署开发成功案例技术剖析
  • 曝光铁三角
  • 三维重建(十四)——铰接类文章整理
  • 前端面试-JavaScript 数据类型详解
  • Kubernetes控制平面组件:APIServer 基于匿名请求的认证机制详解