题目描述

Lemon觉得他需要一个复杂的密码来保证他的帐号的安全。他经过多日思考,决定使用一个长度为奇数的回文串来作为他的密码。
  但是这个回文串太长了,Lemon记不住,于是Lemon决定把它记在本子上。当然直接把密码明文记录实在太愚蠢了,于是Lemon决定在记录时加入一些无意义的字符以保证密码的安全。
  具体来说,假设Lemon的密码串是S,Lemon选择了一个不超过len(S)/2的正整数x,然后把S的前x个字符组成的字符串设为Left,把S的后x个字符组成的字符串设为Right,把S其余的字符组成的字符串设为Mid.
  Lemon实际记录在密码本上的内容是A+Left+B+Mid+C+Right. 其中A,B,C都是无意义的字符串(有可能是空串)。他觉得这样就很安全了。
  某一天,Melon无意发现了Lemon的笔记本,并发现了这个字符串。Melon决定把Lemon的密码破解出来。但是显然有不计其数的可能密码。
  Melon认为,Lemon的密码一定很长,于是他想知道,这个字符串里隐藏的最长可能的密码有多长呢?

输入格式

输入数据第一行包含一个正整数N,表示字符串的长度。
  数据数据第二行包含一个长度为N的字符串,仅由小写字母组成,表示需要破译的字符串。

输出格式

输出数据仅包含一个整数,表示最长可能的密码的长度。
输入样例
  25
  orzabcdxyzefgfeqwertydcba
输出样例
  13
提示
  最长的可能的密码是abcdefgfedcba,长度为13
  Lemon选择的x=4
  Left="abcd" Right="dcba" Mid="efgfe"
  A="orz" B="xyz" C="qwerty"
  时间限制1s
  对于20%的数据,满足N<=20
  对于40%的数据,满足N<=300
  对于60%的数据,满足N<=2000
  对于100%的数据,满足N<=100000

分析

在网上找了半天题解啥都没找到最后放弃了,去问的Master_Yi

由于Right的右端点一定是原序列中的右端点,所以我们可以去枚举Right的左端点,也可以说是Right的长度,然后用hash值去找与它对称的Left

用贪心的思想去找最左边的且与Right对称的 Left(这样可以给中间的mid留下足够的长度),从小到大枚举Left的左端点的坐标,可以发现它有单调性的

模糊感性证明

如果当前枚举的左端点形成的Left与Right不对称,之后的枚举新的Right的长度时,以这个点为左端点的Left肯定与Right不对称

所以最左边与Right对称的Left的左端点一定随着Right的长度单增(或者说不下降

于是就可以O(n)确定Left和Right,剩下中间的Mid,因为Mid一定是个回文串,可以用manacher预处理每个点的len数组,即以这个点为对称中心的最长子串长度

设中间剩下的区间为(l,r),二分一下Mid的半径,设为k,用st表检验(l+k,r-k)中是否有len数组的值大于等于k的,如果有就更新答案,然后继续搜索。

整了这么多东西,发现复杂度只有nlogn。。。。。。

Code

#include<cstdio>
#include<algorithm>
using namespace std;
int n,ans,ha[],st[][],bw[],lg[];char ch[];
int que(int l,int r){return l<=r?max(st[l][lg[r-l+]],st[r-(<<lg[r-l+])+][lg[r-l+]]):;}
int main()
{
scanf("%d%s",&n,ch+);bw[]=;
for(int i=;i<=n+;i++)lg[i]=lg[i/]+;
for(int i=,r=,mid=;i<=n;bw[i]=bw[i-]*,i++)
{
st[i][]=r>i?min(st[mid*-i][],r-i):;
while(ch[i-st[i][]]==ch[i+st[i][]])st[i][]++;
if(r<i+st[i][])r=i+st[i][],mid=i;ha[i]=(ch[i]-'a'+)+ha[i-]*;
}
for(int k=;k<=;k++)for(int i=;i<=n;i++)st[i][k]=max(st[i][k-],i+(<<(k-))<=n?st[i+(<<(k-))][k-]:);
for(int i=n,j=,tmp=;i>=;i--)
{
tmp=ch[i]-'a'++tmp*;
while((j<n-i+||ha[j]-ha[j-(n-i+)]*bw[n-i+]!=tmp)&&j<=n)j++;
int l=,r=(i-j)/,mid,ret;
while(l<=r&&j<=i)
{
mid=(l+r)>>;
if(que(j+mid,i-mid)>=mid)ret=mid,l=mid+;
else r=mid-;
}
if(j<=i)ans=max((n-i+)*+ret*-,ans);
}
printf("%d\n",ans);
}

【CSP膜你赛】柠檬的密码(manacher 二分 单调性 st表)的更多相关文章

  1. 【CSP膜你赛】ATM

    题目描述 小沈阳在小品里说过:“人生最痛苦的事情是人死了,钱还没花掉”. 于是小宋(80 岁)决定要将所有的储蓄从 ATM 机中取出花光. 小宋忘记 了她有多少存款(银行卡密码她是记得的 2333), ...

  2. 【CSP膜你赛】大逃亡

    题目描述 魔王撒旦为了建立魔物的乐土,率领亚多拉玛雷克.艾谢尔.路西菲尔.以 及马纳果达这四位恶魔大元帅进攻人类世界.然而此时手持圣剑的勇者艾米莉亚出现了.  战败的魔王逃跑时穿越到了地球,以真奥贞夫 ...

  3. cdcqの省选膜你赛

    cdcqの省选膜你赛 比赛当天因为在杠hnoi2016的大数据结构没有参加,今天补了一下.挺好玩的虽然不看一句话题意的话真的卡读题 此生无悔入东方,来世愿生幻想乡 2651. 新史「新幻想史 -现代史 ...

  4. 【BZOJ3325】[Scoi2013]密码 Manacher

    [BZOJ3325][Scoi2013]密码 Description Fish是一条生活在海里的鱼.有一天他很无聊,就到处去寻宝.他找到了位于海底深处的宫殿,但是一扇带有密码锁的大门却阻止了他的前进. ...

  5. Java 第十一届 蓝桥杯 省模拟赛 凯撒密码加密

    凯撒密码加密 题目 问题描述 给定一个单词,请使用凯撒密码将这个单词加密. 凯撒密码是一种替换加密的技术,单词中的所有字母都在字母表上向后偏移3位后被替换成密文.即a变为d,b变为e,-,w变为z,x ...

  6. bzoj 3325 密码 - Manacher

    题目传送门 需要root权限的传送点 题目大意 已知一个串,以每个字符为中心的最长回文串长,以及每两个字符中间为中心的最长回文串长.求字典序最小的这样一个串.题目保证有解. 考虑Manacher的过程 ...

  7. HDU 5371 (2015多校联合训练赛第七场1003)Hotaru&#39;s problem(manacher+二分/枚举)

    pid=5371">HDU 5371 题意: 定义一个序列为N序列:这个序列按分作三部分,第一部分与第三部分同样,第一部分与第二部分对称. 如今给你一个长为n(n<10^5)的序 ...

  8. Solution -「NOI.AC 省选膜你赛」T2

      这道题就叫 T2 我有什么办法www 题目 题意简述   给定一个字符串 \(s\),其长度为 \(n\),求无序子串对 \((u,v)\) 的个数,其中 \((u,v)\) 满足 \(u,v\) ...

  9. 【良心noip膜你赛】总结

    一点都不良心!!!! AK 快乐爆零快乐!!! 1. A. value512mb 1s规定一个区间的价值为这个区间中所有数 and 起来的值与这个区间所有数 or 起来的值的乘积.例如 3 个数 2, ...

随机推荐

  1. Jenkins首次进入的一些设置及配置

    1.将Jenkins显示页面修改为中文环境 首先安装中文的插件:在manage Jenkins-Manage Plugins-可选插件 下载完成之后,在系统设置里边,修改为中文格式:manage Je ...

  2. Django--模型层进阶

    目录 QuerySet对象 可切片 可迭代 惰性查询 缓存机制 何时查询集不会被缓存? exists()与iterator()方法 exists() iterator() 中介模型 查询优化 表数据 ...

  3. Beego 学习笔记14:Session控制

    Session控制 1>     Session常用来作为全局变量使用,比如记录当前登录的用户,或者页面之间传递数据使用. 2>     Beego框架内置了 session 模块,目前 ...

  4. Java开发环境之Git

    查看更多Java开发环境配置,请点击<Java开发环境配置大全> 拾叁章:Git安装教程 1)去官网下载Git安装包 https://gitforwindows.org/ 2)安装 双击执 ...

  5. java8中日期字符串的月日时分秒自动补零

    需求:如字符串2019-7-1 9:6:5转成2019-07-01 09:06:05 java8实现如下: public static String getStartDate(String start ...

  6. Win10如何设置插入鼠标后自动禁用触摸板

    首先按“Windows+R”键,调出运行窗口.  然后输入“control”然后点击“确定”!  打开Win10控制面板  在“控制面板”中,选择“硬件和声音”!  选择“AUSU Amart Ges ...

  7. MinGW-w64离线安装

    1.下载 如果你能从在线 安装,那最好就在线安装吧. 如果你能连上官网,那可以选择从官网去下载,地址:https://osdn.net/projects/mingw/releases/ https:/ ...

  8. BST二叉树的二分查找

    900. 二叉搜索树中最接近的值 中文 English 给一棵非空二叉搜索树以及一个target值,找到在BST中最接近给定值的节点值 样例 样例1 输入: root = {5,4,9,2,#,8,1 ...

  9. 【转载】jmeter-命令行执行脚本

    原文地址:https://blog.csdn.net/qq_35451939/article/details/79643560 日常测试过程中发现,在大数量并发时,jmeterGUI界面时长宕机.卡死 ...

  10. 高小兰 201671010414 实验十四 团队项目评审&课程学习总结

    项目 内容 软件工程 https://www.cnblogs.com/nwnu-daizh/ 作业要求 https://www.cnblogs.com/sunmiaokun/p/11095027.ht ...