[SHOI2011]双倍回文
Description
Input
输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容。
Output
输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。
Sample Input
ggabaabaabaaball
Sample Output
HINT
N<=500000
首先manacher求出len数组
我们发现一个一个以i为中心的回文串[l,r]是双倍回文
[i,r]也是一个回文串,设这个串的中心为j
求出len数组后,可以写出条件:
$j<=i+\frac{len_i}{2}$
$i>=j-len_j$
我们发现从小到大枚举$i$(也可以从大到小枚举j,换一种枚举方式)
这样一个满足$i>=j-len_j$的$j$同样满足$i+x>=j-len_j$
用一个STL的set,维护j,每次找到小于$i+\frac{len_i}{2}$的最大j
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
struct Node
{
int x,id;
}a[];
set<int>S;
int n,loc,mx,len[],po,b[],ans;
char ch[],s[];
bool cmp(Node a,Node b)
{
return a.id-a.x<b.id-b.x;
}
int main()
{int i,j;
cin>>n;
scanf("%s",ch+);
for (i=;i<=n;i++)
{
s[++loc]='#';
s[++loc]=ch[i];
}
s[++loc]='#';s[++loc]='?';
for (i=;i<=loc;i++)
{
if (mx>i)
len[i]=min(mx-i,len[*po-i]);
else len[i]=;
while (s[i-len[i]]==s[i+len[i]]) len[i]++;
if (i+len[i]>mx)
{
mx=i+len[i];
po=i;
}
}
for (i=;i<=n;i++)
a[i].x=(len[i*+]-)/,a[i].id=i,b[i]=a[i].x;
sort(a+,a+n+,cmp);
loc=;ans=;
for (i=;i<=n;i++)
{
while (loc<=n&&a[loc].id-a[loc].x<=i)
S.insert(a[loc].id),loc++;
set<int>::iterator it;
it=S.upper_bound(i+b[i]/);
if (it==S.begin()) continue;
ans=max(ans,*(--it)-i);
}
cout<<ans*;
}
[SHOI2011]双倍回文的更多相关文章
- BZOJ2342: [Shoi2011]双倍回文
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 923 Solved: 317[Submit][Status ...
- 2018.06.30 BZOJ 2342: [Shoi2011]双倍回文(manacher)
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符串 ...
- BZOJ 2342: [Shoi2011]双倍回文 马拉车算法/并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1123 Solved: 408 题目连接 http://w ...
- [SHOI2011]双倍回文 manacher
题面: 洛谷:[SHOI2011]双倍回文‘ 题解: 首先有一个性质,本质不同的回文串最多O(n)个. 所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间 ...
- bzoj 2342: [Shoi2011]双倍回文 -- manacher
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符 ...
- BZOJ2342 Shoi2011 双倍回文 【Manacher】
BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...
- Manacher || BZOJ 2342: [Shoi2011]双倍回文 || Luogu P4287 [SHOI2011]双倍回文
题面:[SHOI2011]双倍回文 题解:具体实现时,就是在更新mr时维护前半段是回文串的最长回文串就好了 正确性的话,因为到i时如果i+RL[i]-1<=mr,那么答案肯定在i之前就维护过了: ...
- BZOJ2342[Shoi2011]双倍回文——回文自动机
题目描述 输入 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. 输出 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文 ...
- bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)
https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...
随机推荐
- Leetcode 27——Remove Element
Given an array and a value, remove all instances of that value in-place and return the new length. D ...
- W班-项目选题报告成绩
作业链接 https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1715W/homework/907 作业要求 1份团队选题报告(word电 ...
- C语言博客作业—一二维数组
一.PTA实验作业 题目1:7-2 求整数序列中出现次数最多的数 1. 本题PTA提交列表 2. 设计思路 Begin 输入整数个数N 定义数组a[N] 输入数组a for(i 0 to N-1){/ ...
- python的项目结构
项目结构 知识点 创建项目,编写 __init__ 文件 使用 setuptools 模块,编写 setup.py 和 MANIFEST.in 文件 创建源文件的发布版本 项目注册&上传到 P ...
- hdu 3642 Get The Treasury
Get The Treasury http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Othe ...
- 数据结构与算法 —— 链表linked list(01)
链表(维基百科) 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer).由于不必须按顺序存储, ...
- Golang学习--平滑重启
在上一篇博客介绍TOML配置的时候,讲到了通过信号通知重载配置.我们在这一篇中介绍下如何的平滑重启server. 与重载配置相同的是我们也需要通过信号来通知server重启,但关键在于平滑重启,如果只 ...
- 剑指offer-数组中出现次数超过一半的数字
题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...
- Electron的代码调试
刚接触Electron,尝试调试程序时,竟无从下手,所以把这个过程做了下记录 参考工程 根据Electron的官方文档:使用 VSCode 进行主进程调试:https://electronjs.org ...
- 微信小程序组件学习中
一.轮播图 wxml代码: <swiper indicator-dots="true" autoplay="true" duration="10 ...