Codeforces 126B Password(Z算法)
题意
给定一个字符串 \(s\) ,求一个子串 \(t\) 满足 \(t\) 是 \(s\) 的前缀、后缀且在除前缀后缀之外的地方出现过。
\(1 \leq |s| \leq 10^6\)
思路
\(\text{Z}\)算法是一个和 \(\text{Manacher}\)算法很像的字符串算法,功能是求出一个 \(z\) 数组,代表以 \(i\) 开头的后缀同整个串的 \(\text{lcp}\) 。
首先回顾一下 \(\text{Manacher}\)算法的流程。
int pos,r=0;
FOR(i,1,n) //字符串Manacher是在原字符串每两字符间插入'#'的字符串。
{
if(i<=r)p[i]=std::min(p[(pos<<1)-i],r-i+1);
else p[i]=1;
while(i-p[i]>=1&&i+p[i]<=n&&mnc[i-p[i]]==mnc[i+p[i]])p[i]++;
if(chk_max(r,i+p[i]-1))pos=i;
}
\(\text{Manacher}\)算法通过维护了目前扫到的最有端点,使得复杂度变成线性(可以发现把第 \(3,4\) 行替换成 p[i]=1; ,就变成了 \(O(n^2)\) 的暴力。
把它稍微变一下,就变成了\(\text{Z}\)算法。
z[1]=n;
int l,r=0;
FOR(i,2,n)
{
if(i<=r)z[i]=std::min(z[i-l+1],r-i+1);
else z[i]=0;
while(i+z[i]<=n&&str[i+z[i]]==str[1+z[i]])z[i]++;
if(chk_max(r,i+z[i]-1))l=i;
}
仍然是通过最右端点保证复杂度,和 \(\text{Manacher}\)完全一个道理。
对于这道题目而言,先考虑既是前缀又是后缀的限制,只需要对原串 \(str\) 求一下 \(z\) 数组,如果一个位置 \(i\) 满足 \(z[i]=|str|-i+1\) ,那么 \([i,|str|]\) 这个串就既是前缀又是后缀了。至于这个串还得在不是前缀不是后缀的地方出现过,我们可以对 \(z\) 数组求一个前缀最大值(除了 \(z[1]\) ,\(z[1]\) 没什么意义),这个前缀最大值就代表出现过的最长的前缀,因为你需要的串 \([i,|str|]\) 肯定也是个前缀,所以就看 \(|str|-i+1\) 是不是小于等于前缀最大值即可。
代码
#include<bits/stdc++.h>
#define FOR(i,x,y) for(int i=(x),i##END=(y);i<=i##END;++i)
#define DOR(i,x,y) for(int i=(x),i##END=(y);i>=i##END;--i)
template<typename T,typename _T>inline bool chk_min(T &x,const _T y){return y<x?x=y,1:0;}
template<typename T,typename _T>inline bool chk_max(T &x,const _T y){return x<y?x=y,1:0;}
typedef long long ll;
const int N=1e6+5;
char str[N];int z[N];
int n;
void get_z(char *str,int n)
{
z[1]=n;
int l,r=0;
FOR(i,2,n)
{
if(i<=r)z[i]=std::min(z[i-l+1],r-i+1);
else z[i]=0;
while(i+z[i]<=n&&str[i+z[i]]==str[1+z[i]])z[i]++;
if(chk_max(r,i+z[i]-1))l=i;
}
}
int main()
{
scanf("%s",str+1);
n=strlen(str+1);
get_z(str,n);
int r=0;
FOR(i,2,n)
{
if(z[i]==n-i+1&&r>=n-i+1)
{
FOR(j,1,n-i+1)putchar(str[j]);
return 0;
}
chk_max(r,z[i]);
}
puts("Just a legend");
return 0;
}
Codeforces 126B Password(Z算法)的更多相关文章
- Codeforces 126B. Password(KMP,DP)
Codeforces 126B. Password 题意:一个字符串,找出最长的子串t,它既是前缀又是后缀,还出现在中间.输出t,不存在则输出Just a legend. 思路:利用KMP算法处理出n ...
- CodeForces 126B Password
题目链接:http://codeforces.com/problemset/problem/126/B 题目大意: 多组数据每组给定1个字符串S,问是否存在S的一个尽量长的子串,同时是S的前缀和后缀, ...
- Codeforces 126B. Password (KMP)
<题目链接> 题目大意:给定一个字符串,从中找出一个前.中.后缀最长公共子串("中"代表着既不是前缀,也不是后缀的部分). 解题分析:本题依然是利用了KMP中next数 ...
- CodeForces - 1051E :Vasya and Big Integers(Z算法 & DP )
题意:给定字符串S,A,B.现在让你对S进行切割,使得每个切割出来的部分在[A,B]范围内,问方案数. 思路:有方程,dp[i]=Σ dp[j] (S[j+1,i]在合法范围内). 假设M和 ...
- Z算法
Z算法 Z算法是一种用于字符串匹配的算法.此算法的核心在于\(z\)数组以及它的求法. (以下约定字符串下标从\(1\)开始) \(\bm z\)数组和Z-box 定义\(z\)数组:\(z_{a,i ...
- 【算法】字符串匹配之Z算法
求文本与单模式串匹配,通常会使用KMP算法.后来接触到了Z算法,感觉Z算法也相当精妙.在以前的博文中也有过用Z算法来解决字符串匹配的题目. 下面介绍一下Z算法. 先一句话讲清楚Z算法能求什么东西. 输 ...
- Z算法板子
给定一个串$s$, $Z$算法可以$O(n)$时间求出一个$z$数组 $z_i$表示$s[i...n]$与$s$的前缀匹配的最长长度, 下标从$0$开始 void init(char *s, int ...
- [Codeforces 364D]Ghd(随机算法+gcd)
[Codeforces 364D]Ghd(随机算法) 题面 给出n个正整数,在其中选出n/2(向上取整)个数,要求这些数的最大公约数最大,求最大公约数的最大值 分析 每个数被选到的概率\(\geq \ ...
- 【Codeforces 126B】Password
[链接] 我是链接,点我呀:) [题意] 给你一个字符串s 让你从中选出来一个字符串t 这个字符串t是s的前缀和后缀 且在除了前缀和后缀之外的中间部位出现过. 且要求t的长度最长. 让你输出这个字符串 ...
随机推荐
- Autoware 笔记 No. 5——基于GNSS的定位
1. 前言 在之前的笔记No.2 中,我们直接采用ndt_matching的方法实现定位,但需要在打开rviz中,通过2D Pose Estimate指定初始位置.加入GNSS后,可以帮助ndt_ma ...
- 在 .NET Core 中使用异步的 ADO.NET 的简单示例
直接贴代码: Program.cs using Microsoft.Extensions.Configuration; using System; using System.Data; using S ...
- 使用 Xbox Game 录制桌面视频(录制音频)
使用 Xbox Game 录制桌面视频(附带音频) 前言:可能自己音频输出的问题,一直无法用工具录制桌面的音频,而最后发现利用 Xbox Game 录制游戏视频的功能很好地解决我们的问题. 1)打开游 ...
- WEBAPI 设置上传文件大小
参考资料:https://stackoverflow.com/questions/33399267/cors-error-when-uploading-larger-files https:// ...
- Asp.Net MVC 的19个管道事件
httpApplication调用ProcessRequest方法,内部执行19个管道事件,如下 BeginRequest 开始处理请求 AuthenticateRequest 授权验证请求开始,获 ...
- Python【day 12】生成器和推导式
一.生成器和生成器函数1.生成器和生成器函数的概念 1.生成器的本质是迭代器 2.函数中包含yield,就是生成器函数 2.生成器函数的写法 def func(): a =10 yield 20 ge ...
- Jquery选择器与样式操作
jquery选择器 jquery用法思想一 选择某个网页元素,然后对它进行某种操作 jquery选择器 jquery选择器可以快速地选择元素,选择规则和css样式相同,使用length属性判断是否选择 ...
- 【转】Git使用教程之远程仓库
1.远程仓库 在了解之前,先注册github账号,由于你的本地Git仓库和github仓库之间的传输是通过SSH加密的,所以需要一点设置: 第一步:创建SSH Key.在用户主目录下,看看有没有.ss ...
- ios-tableview加载卡顿的解决方案
参考文章:http://www.cocoachina.com/articles/11968 总结: 提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法 ...
- mac上配置python的安装环境杂记
现在的python的包都是通过pip安装的. 所以非常重要的一步是配置pip的安装源 vi ~/.pip/pip.conf [global] index-url = http://pypi.douba ...