[SHOI2011]双倍回文 manacher
题面:
洛谷:[SHOI2011]双倍回文‘
题解:
首先有一个性质,本质不同的回文串最多O(n)个。
所以我们可以对于每个i,求出以这个i为结尾的最长回文串,然后以此作为长串,并判断把这个长串从中间劈开后左边的一半是否也是一个回文串(判断左边那半的中点的回文半径是否可以跨过当前长串的中点)。
复杂度O(n)
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define R register int 5 #define AC 1001000 6 7 int n, pos, maxn, ans; 8 int r[AC]; 9 char a[AC], s[AC]; 10 11 void pre(){ 12 scanf("%d%s", &n, a + 1); 13 s[0] = '$', s[1] = '#'; 14 for(R i = 1; i <= n; i ++) s[2 * i] = a[i], s[2 * i + 1] = '#'; 15 } 16 17 inline void upmax(int &a, int b){ 18 if(b > a) a = b; 19 } 20 21 void manacher() 22 { 23 int b = 2 * n; 24 for(R i = 1; i <= b; i ++) 25 { 26 r[i] = (maxn > i) ? min(r[2 * pos - i], maxn - i + 1) : 1;//这里要取min 27 while(s[i - r[i]] == s[i + r[i]]) ++ r[i]; 28 29 int last = i - r[i] + 1, Next = i + r[i] - 1; 30 if(s[last] == '#') ++ last, -- Next; 31 if(i + r[i] - 1 > maxn && last <= i)//last才是整个串的开头 32 { 33 for(R j = maxn + 1; j <= Next; j ++) 34 { 35 int l = 2 * i - j;//获取串头 36 int sum = (j - l + 1 + 1) >> 1; 37 if(s[j] == '#' || sum % 4) continue;//中间是获取实际字符数 38 int tmp = (l + j) >> 1, k = (tmp + l) >> 1; 39 if(k + r[k] - 1 >= tmp) upmax(ans, sum); 40 } 41 } 42 43 if(i + r[i] - 1 > maxn) pos = i, maxn = i + r[i] - 1; 44 } 45 printf("%d\n", ans); 46 } 47 48 int main() 49 { 50 //freopen("in.in", "r", stdin); 51 pre(); 52 manacher(); 53 //fclose(stdin); 54 return 0; 55 }
View Code
转载于:https://www.cnblogs.com/ww3113306/p/10066792.html
[SHOI2011]双倍回文 manacher相关推荐
- BZOJ2342 Shoi2011 双倍回文 【Manacher】
BZOJ2342 Shoi2011 双倍回文 Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输 ...
- 【BZOJ-2342】双倍回文 Manacher + 并查集
2342: [Shoi2011]双倍回文 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1799 Solved: 671 [Submit][Sta ...
- 洛谷P4287 [SHOI2011]双倍回文 题解
洛谷P4287 [SHOI2011]双倍回文 题解 题目链接:P4287 [SHOI2011]双倍回文 题意: 记字符串 www 的倒置为 wRw^RwR .例如 (abcd)R=dcba(\tt{a ...
- 洛谷-P4287 双倍回文(Manacher)
双倍回文 Manacher算法用的还是不够熟悉啊,被卡了好久...一会再写个回文自动机的做法吧 清晰的回文自动机写法 题意:若一个回文串左半部分和有半部分分别为一个回文串,则这个回文串被称为双倍回文串 ...
- BZOJ 2342 [Shoi2011]双倍回文(manacher+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2342 [题目大意] 记Wr为W串的倒置,求最长的形如WWrWWr的串的长度. [题解] ...
- [BZOJ2342] [Shoi2011]双倍回文(manacher)
传送门 manacher...... 先跑一边manacher是必须的 然后枚举双倍回文串的对称轴x 把这个双倍回文串分成4段,w wR w wR 发现,只有当 y <= x + p[x] / ...
- P4287 [SHOI2011]双倍回文
文章目录 ResultResultResult HyperlinkHyperlinkHyperlink DescriptionDescriptionDescription SolutionSoluti ...
- BZOJ2342[Shoi2011]双倍回文——回文自动机
题目描述 输入 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. 输出 输出文件只有一行,即:输入数据中字符串的最长双倍回文子串的长度,如果双倍回文 ...
- [Shoi2011]双倍回文
Description Input 输入分为两行,第一行为一个整数,表示字符串的长度,第二行有个连续的小写的英文字符,表示字符串的内容. Output 输出文件只有一行,即:输入数据中字符串的最长双倍 ...
最新文章
- 【Netty】Netty 核心组件 ( Future | Channel | Selector | ChannelHandler )
- oracle中year类型吗,为什么表名this_year_end+next_year在Oracle数据库中无效?()
- Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解(1)
- 0-pyqt5开发环境搭建
- Git——单人操作及多人协同操作
- inno setup打包的安装包如何在卸载完程序后可以继续安装_这两个方法就够了!快速制作Python程序Windows安装包...
- 实现jdbc连接mysql_Java JDBC连接MYSQL数据库教程(实现)
- 花了10块钱,我在朋友圈成为了富豪...
- idea中出现Please, configure Web Facet first问题
- AquaFold.Data.Studio.v6.5
- vue 中基于drag drop拖放实现左菜单和右画布的功能
- Numpy一维array转置
- android获取系统签名,Android apk签名详解——AS签名、获取签名信息、系统签名、命令行签名...
- Spring Cloud 基本理论概述
- shell 关闭电脑wifi_笔记本通过命令配置wifi win7系统
- 阿里巴巴矢量图的使用方法详细教程
- 面向全局搜索的自适应领导者樽海鞘群算法-附代码
- Vue3+Vite项目使用mockjs模拟数据
- 如何实现团队高效协作沟通?远程办公软件华为云WeLink高效沟通指南
- 如何拯救一台GRUB 2启动失败的Linux电脑
热门文章
- linux下zabbix安装
- CRC16循环冗余校验 RTU-MODBUS标准 Linux C
- Vue基础之Vue条件渲染
- std::function和std::bind
- A Quantization-Friendly Separable Convolution for MobileNets
- 基于 opencv 的图像处理入门教程
- python selenium 处理弹窗_python+selenium 抓取弹出对话框信息
- css3-12 transition+css或transform实现过渡动画
- linux3.0.4编译LDD中的scull全过程
- 分布式文件系统虚拟目录及命名空间的实现方法