题意

给定一个字符串 \(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算法)的更多相关文章

  1. Codeforces 126B. Password(KMP,DP)

    Codeforces 126B. Password 题意:一个字符串,找出最长的子串t,它既是前缀又是后缀,还出现在中间.输出t,不存在则输出Just a legend. 思路:利用KMP算法处理出n ...

  2. CodeForces 126B Password

    题目链接:http://codeforces.com/problemset/problem/126/B 题目大意: 多组数据每组给定1个字符串S,问是否存在S的一个尽量长的子串,同时是S的前缀和后缀, ...

  3. Codeforces 126B. Password (KMP)

    <题目链接> 题目大意:给定一个字符串,从中找出一个前.中.后缀最长公共子串("中"代表着既不是前缀,也不是后缀的部分). 解题分析:本题依然是利用了KMP中next数 ...

  4. CodeForces - 1051E :Vasya and Big Integers(Z算法 & DP )

    题意:给定字符串S,A,B.现在让你对S进行切割,使得每个切割出来的部分在[A,B]范围内,问方案数. 思路:有方程,dp[i]=Σ dp[j]   (S[j+1,i]在合法范围内).    假设M和 ...

  5. Z算法

    Z算法 Z算法是一种用于字符串匹配的算法.此算法的核心在于\(z\)数组以及它的求法. (以下约定字符串下标从\(1\)开始) \(\bm z\)数组和Z-box 定义\(z\)数组:\(z_{a,i ...

  6. 【算法】字符串匹配之Z算法

    求文本与单模式串匹配,通常会使用KMP算法.后来接触到了Z算法,感觉Z算法也相当精妙.在以前的博文中也有过用Z算法来解决字符串匹配的题目. 下面介绍一下Z算法. 先一句话讲清楚Z算法能求什么东西. 输 ...

  7. Z算法板子

    给定一个串$s$, $Z$算法可以$O(n)$时间求出一个$z$数组 $z_i$表示$s[i...n]$与$s$的前缀匹配的最长长度, 下标从$0$开始 void init(char *s, int ...

  8. [Codeforces 364D]Ghd(随机算法+gcd)

    [Codeforces 364D]Ghd(随机算法) 题面 给出n个正整数,在其中选出n/2(向上取整)个数,要求这些数的最大公约数最大,求最大公约数的最大值 分析 每个数被选到的概率\(\geq \ ...

  9. 【Codeforces 126B】Password

    [链接] 我是链接,点我呀:) [题意] 给你一个字符串s 让你从中选出来一个字符串t 这个字符串t是s的前缀和后缀 且在除了前缀和后缀之外的中间部位出现过. 且要求t的长度最长. 让你输出这个字符串 ...

随机推荐

  1. 阿里开源 Dragonwell JDK 重磅发布 GA 版本:生产环境可用

    今年 3 月份,阿里巴巴重磅开源 OpenJDK 长期支持版本 Alibaba Dragonwell的消息,在很长一段时间内都是开发者的讨论焦点,该项目在 Github 上的 Star 数迅速突破 1 ...

  2. java架构之路-(mysql底层原理)Mysql索引和查询引擎

    今天我们来说一下我们的mysql,个人认为现在的mysql能做到很好的优化处理,不比收费的oracle差,而且mysql确实好用. 当我们查询慢的时候,我会做一系列的优化处理,例如分库分表,加索引.那 ...

  3. C++中Lambda表达式转化为函数指针

    // ----------------------------------------------------------- auto combineCallbackLambda = [](GLdou ...

  4. SqLite踩的坑

    一.修改表名称.增加字段.查询表结构.修改表结构字段类型 .修改表名称 ALTER TABLE 旧表名 RENAME TO 新表名 eg: ALTER TABLE or_sql_table RENAM ...

  5. 如何使用Charles让手机访问PC自定义域名?

    需求:移动端访问PC上的自定义域名,如在Nginx上配置的域名 ​ 如vv.zzcloud.com这个域名在pc上是通过host映射的方式访问,现在需要在手机上访问到这个域名. 工具:Charles代 ...

  6. mac中使用expect脚本,让iTerms保存密码登录ssh

    最近工作中需要使用ssh连接到centos服务器中,以前公司都是直接配的私钥就可以免密登录了.这里还用的密码. 由于,我一直用的是iTerm2,所以在网上搜索了下,找到了一种方案,那就是expect脚 ...

  7. Spring Boot 使用 Log4j2 & Logback 输出日志到 EKL

    文章目录 1.ELK 介绍 2.环境.软件准备 3.ELK 环境搭建 4.Spring Boot 配置示例 4.1.Log4j2 方式配置 4.2.Logback 方式配置 1.ELK 介绍 ELK ...

  8. web前端-bootstrap

    1.什么是bootstrap 前端开发开源工具包 ,包含css样式库+jq插件 ,ui效果非常好 ,都是通过给标签加class选择器来实现功能的 2.特点 响应式布局:使用栅格系统可以把页面呈现在不同 ...

  9. Linux kali信息探测以及 Nmap 初体验

    Nmap是一个开源的网络连接端口扫描软件(内置于kali中) 打开Nmap: > nmap 打开桌面化Nmap——zenmap: > zenmap Nmap支持多种扫描方式,用法简单,参数 ...

  10. wpf 工程生成dll

    在WPF项目里,当工程里包含窗体时候, 不可以使用类库的方式生产dll,虽然系统支持引用exe 文件,但总是觉得不如dll习惯,后来发现,新建个项目,类型选择“WPF自定义类件库”,名称和工程名称相同 ...