【BZOJ-2342】双倍回文 Manacher + 并查集
2342: [Shoi2011]双倍回文
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1799 Solved: 671
[Submit][Status][Discuss]
Description
Input
输入分为两行,第一行为一个整数n,表示字符串的长度,第二行有n个连续的小写的英文字符,表示字符串的内容。
Output
输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文子串不存在,则输出0。
Sample Input
ggabaabaabaaball
Sample Output
HINT
N<=500000
Source
Solution
看完题大体的思路就是先一遍Manacher,O(n)求出回文串,然后进行判断
题目中说的很清楚,双倍回文串长度一定是4的倍数,即为偶数,那么Manacher出来的回文串中心一定在字符间添加的'#'上
那么考虑要求的东西 y+p[y]>=x && y>=x-p[x]/2,思考一个枚举的方法
枚举j,如果j不能覆盖到当前的i,那么一定是不符合覆盖到i+1的,所以,之后的所有事和它无关,可以忽略,这样想,维护一下就好了,采取并查集
Code
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- #define maxn 500010
- char S[maxn],s[maxn<<];
- int n,len,mx,id,p[maxn<<],fa[maxn<<],ans;
- void PreWork()
- {
- memset(p,,sizeof(p));
- len=n<<|;
- for (int i=; i<=n; i++)
- s[i<<]=S[i],s[i<<|]='#';
- s[]='$'; s[]='#'; s[len+]='%';
- }
- void Manacher()
- {
- PreWork();
- for (int i=; i<=len; i++)
- {
- if (mx>i) p[i]=min(p[id*-i],mx-i);
- else p[i]=;
- while (s[i-p[i]]==s[i+p[i]]) p[i]++;
- if (p[i]+i>mx) mx=p[i]+i,id=i;
- }
- }
- int find(int x) {if (fa[x]==x) return x; else return fa[x]=find(fa[x]);}
- int main()
- {
- scanf("%d",&n); scanf("%s",S+);
- Manacher();
- for (int i=; i<=len; i++)
- if (s[i]=='#') fa[i]=i; else fa[i]=i+;
- for (int i=; i<=len-; i+=)
- {
- int f=find(max(i-p[i]/,));
- while (f<i && f+p[f]<i) fa[f]=find(f+),f=fa[f];
- if (f<i && (i-f)*>ans) ans=(i-f)*;
- }
- printf("%d\n",ans);
- return ;
- }
【BZOJ-2342】双倍回文 Manacher + 并查集的更多相关文章
- BZOJ 2342 双倍回文(manacher算法)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2342 题意:定义双倍回文串为:串的长度为4的倍数且串的前一半.后一半.串本身均是回文的. ...
- bzoj 2342: 双倍回文 回文自动机
题目大意: 定义双倍回文串的左一半和右一半均是回文串的长度为4的倍数的回文串 求一个给定字符串中最长的双倍回文串的长度 题解: 我们知道可以简单地判定以某一点结尾的最长回文串 我们知道可以简单地判定以 ...
- [BZOJ 2342] 双倍回文
Link:https://www.lydsy.com/JudgeOnline/problem.php?id=2342 Algorithm: 解决回文串问题,一般从对称轴下手. 肯定先跑一边Manach ...
- 【做题】BZOJ2342 双倍回文——马拉车&并查集
题意:有一个长度为\(n\)的字符串,求它最长的子串\(s\)满足\(s\)是长度为4的倍数的回文串,且它的前半部分和后半部分都是回文串. \(n \leq 5 \times 10^5\) 首先,显然 ...
- bzoj 2342: [Shoi2011]双倍回文 -- manacher
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Description Input 输入分为两行,第一行为一个整数,表示字符 ...
- [SHOI2011]双倍回文 manacher
题面: 洛谷:[SHOI2011]双倍回文‘ 题解: 首先有一个性质,本质不同的回文串最多O(n)个. 所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间 ...
- BZOJ2342:[SHOI2011]双倍回文(Manacher)
Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输出文件只有一行,即:输入数据中字符串的最长 ...
- [BZOJ2341][Shoi2011]双倍回文 manacher+std::set
题目链接 发现双倍回文串一定是中心是#的回文串. 所以考虑枚举#点.发现以\(i\)为中心的双倍回文的左半部分是个回文串,其中心一定位于\(i-\frac{pal[i]-1}2\)到\(i-1\)之间 ...
- BZOJ 2342: [Shoi2011]双倍回文 [Manacher + set]
题意: 求最长子串使得它有四个相同的回文串SSSS相连组成 枚举中间x 找右边的中间y满足 y-r[y]<=x y<=x+r[x]/2 用个set维护 注意中间只能是# #include ...
随机推荐
- PAT 1013. 数素数 (20)
令Pi表示第i个素数.现任给两个正整数M <= N <= 104,请输出PM到PN的所有素数. 输入格式: 输入在一行中给出M和N,其间以空格分隔. 输出格式: 输出从PM到PN的所有素数 ...
- 032医疗项目-模块三:药品供应商目录模块——供货商药品目录查询功能----------Service层和Action层和调试
我们上一篇文章讲了Dao层代码: 这一篇我们讲解Service层和Action层: Service层: 分为接口和实现类,我们主要看实现类:GysemplServiceImpl package yyc ...
- c语言 指针与数组
关键概念: 1.多个不同类型的指针可以对应同一个地址: 2.(&p)则是这样一种运算,返回一个指针,该指针的值是当时声明p 时开辟的地址,指针的类型是p的类型对应的指针类型: 3.(*p)操作 ...
- Java的性能优化
http://www.toutiao.com/i6368345864624144897/?tt_from=mobile_qq&utm_campaign=client_share&app ...
- 读书摘要,Hackable Projects
完整读完Google的三篇谈Hackable Projects的文章,以及一篇从Test Pyramid看UnitTest的比重.一篇谈Optimal Logging的文章,感觉这5篇在测试.日志两个 ...
- QTableView 添加进度条
记录一下QTableView添加进度条 例子很小,仅供学习 使用QItemDelegate做的实现 有自动更新进度 要在.pro文件里添加 CONFIG += c++ ProgressBarDeleg ...
- Qt学习笔记常用容器
主要说Qt的以下几种容器 1.QList<T> 2.QLinkedList<T> 3.Map<T> 和一些常用的容器方法的使用 qSort qCopy qFind ...
- web 前端常用组件【05】ZTree
web 项目或多或少都会有涉及到什么人员职称树,菜单树,组织机构树等. 历手三四个项目有大有小,采用的树前端都是 Ztree. 有些优秀的J2EE 框架将这些常用的组件都封装起来,作为模块化的组件提供 ...
- Bootstrap系列 -- 4. 文本内容强调
一. 文本强调基本样式 .text-muted:提示,使用浅灰色(#999) .text-primary:主要,使用蓝色(#428bca) .text-success:成功,使用浅绿色(#3c763d ...
- 准标识符(Quasi-dientifier, QI)
Quasi-identifier From Wikipedia, the free encyclopedia Quasi-identifiers are pieces of information t ...