2021 ICPC沈阳 M.String Problem(思维)
Posted lwz_159
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021 ICPC沈阳 M.String Problem(思维)相关的知识,希望对你有一定的参考价值。
题目描述
题目大意
给你一个字符串,求这个字符串的所有前缀字符串中的最大字典序子串。
题目分析
这 个 题 的 思 路 非 常 的 简 单 。 这个题的思路非常的简单。 这个题的思路非常的简单。
首 先 我 们 可 以 发 现 : 对 于 一 个 字 符 串 , 其 字 典 序 最 大 的 子 串 , 这 个 子 串 的 结 尾 一 定 是 整 个 字 符 串 的 结 尾 。 首先我们可以发现:对于一个字符串,其字典序最大的子串,这个子串的结尾一定是整个字符串的结尾。 首先我们可以发现:对于一个字符串,其字典序最大的子串,这个子串的结尾一定是整个字符串的结尾。
证 明 ( 反 证 法 ) : 假 设 字 符 串 范 围 是 [ 1 , n ] , 其 字 典 序 最 大 的 子 串 范 围 是 [ l , r ] ( 1 < l < = r < n ) , 那 么 存 在 一 个 证明(反证法):假设字符串范围是[1,n],其字典序最大的子串范围是[l,r](1<l<=r<n),那么存在一个 证明(反证法):假设字符串范围是[1,n],其字典序最大的子串范围是[l,r](1<l<=r<n),那么存在一个 子 串 [ l , n ] , 而 这 个 子 串 的 字 典 序 是 大 于 [ l , r ] 的 子 串 的 ( 如 果 两 串 前 缀 完 全 一 样 则 比 较 长 度 ) 。 子串[l,n],而这个子串的字典序是大于[l,r]的子串的(如果两串前缀完全一样则比较长度)。 子串[l,n],而这个子串的字典序是大于[l,r]的子串的(如果两串前缀完全一样则比较长度)。
因 此 我 们 只 需 要 找 出 前 缀 字 符 串 最 大 子 串 的 开 头 即 可 。 因此我们只需要找出前缀字符串最大子串的开头即可。 因此我们只需要找出前缀字符串最大子串的开头即可。
我 们 可 以 从 前 往 后 枚 举 每 一 位 , 并 记 录 下 当 前 字 典 序 最 大 的 前 缀 , 以 这 个 前 缀 的 开 头 到 枚 举 的 整 个 前 缀 的 结 尾 来 我们可以从前往后枚举每一位,并记录下当前字典序最大的前缀,以这个前缀的开头到枚举的整个前缀的结尾来 我们可以从前往后枚举每一位,并记录下当前字典序最大的前缀,以这个前缀的开头到枚举的整个前缀的结尾来 作 为 字 典 序 最 大 的 子 串 。 作为字典序最大的子串。 作为字典序最大的子串。
代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iomanip>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PDD pair<double,double>
#define x first
#define y second
using namespace std;
const int N=1e6+5,mod=1e9+7;
int l[N];
char s[N];
int main()
scanf("%s",s+1);
int n=strlen(s+1);
for(int i=1;i<=n;) //枚举字符串的每一位
if(!l[i]) l[i]=i; //如果这一位之前没有记录,那么其最大字串为[i,i]
int j=i,k=i+1;
while(k<=n&&s[j]>=s[k]) //更新所有以i为开头,以k为结尾的最大子串
if(!l[k]) l[k]=i; //如果当前位没被记录过,则以i为开头的子串为其最大子串
if(s[j]==s[k]) j++; //如果当前位j与位k相等,则j+1,继续向后比较(直到决定出谁才是字典序最大的前缀)
else j=i; //如果不相等还在while里,说明以i开头的前缀还是最大的前缀(比较结束,j从新置i)
k++;
while(i<=j) i+=k-j; //跳出了上一个while,说明[i,j]这个前缀字典序小于后面某个子串,则跳到j之后
for(int i=1;i<=n;i++) printf("%d %d\\n",l[i],i);
return 0;
以上是关于2021 ICPC沈阳 M.String Problem(思维)的主要内容,如果未能解决你的问题,请参考以下文章