[POJ3974]Palindrome(后缀数组 || manacher)
求一个串的最长回文子串的长度
1.后缀数组
把这个串反转后接到原串的后面,中间连一个没有出现过的字符。
然后求这个新字符串的某两个后缀的公共前缀的最大值即可。
——代码
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 2000010
#define max(x, y) ((x) > (y) ? (x) : (y)) int n, m, len, ans;
int buc[N], x[N], y[N], sa[N], rank[N], height[N];
char s[N]; inline void build_sa()
{
int i, k, p;
for(i = ; i < m; i++) buc[i] = ;
for(i = ; i < len; i++) buc[x[i] = s[i]]++;
for(i = ; i < m; i++) buc[i] += buc[i - ];
for(i = len - ; i >= ; i--) sa[--buc[x[i]]] = i;
for(k = ; k <= len; k <<= )
{
p = ;
for(i = len - ; i >= len - k; i--) y[p++] = i;
for(i = ; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < m; i++) buc[i] = ;
for(i = ; i < len; i++) buc[x[y[i]]]++;
for(i = ; i < m; i++) buc[i] += buc[i - ];
for(i = len - ; i >= ; i--) sa[--buc[x[y[i]]]] = y[i];
std::swap(x, y);
p = , x[sa[]] = ;
for(i = ; i < len; i++)
x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + k] == y[sa[i] + k] ? p - : p++;
if(p >= len) break;
m = p;
}
} inline void build_height()
{
int i, j, k = ;
for(i = ; i < len; i++) rank[sa[i]] = i;
for(i = ; i < len; i++)
{
if(!rank[i]) continue;
if(k) k--;
j = sa[rank[i] - ];
while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
height[rank[i]] = k;
}
} int main()
{
int i, k, tot = ;
while(scanf("%s", s))
{
if(s[] == 'E' && s[] == 'N' && s[] == 'D') break;
tot++;
ans = ;
m = ;
k = strlen(s);
s[k] = '#';
for(i = ; i < k; i++) s[k + i + ] = s[k - i - ];
len = k << | ;
build_sa();
build_height();
for(i = ; i < len; i++)
if((sa[i - ] < k && sa[i] > k) || (sa[i - ] > k && sa[i] < k))
ans = max(ans, height[i]);
printf("Case %d: %d\n", tot, ans);
}
return ;
}
2.manacher
#include <cstdio>
#include <cstring>
#define N 2100000
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y)) int p[N];
char s[N];
int n, pos, maxright, ans; int main()
{
int i, cnt = 0;;
while(scanf("%s", s + 1) && s[1] != 'E')
{
cnt++;
n = strlen(s + 1);
s[0] = '$', s[n * 2 + 1] = '#';
for(i = n; i >= 1; i--)
s[i * 2] = s[i], s[i * 2 - 1] = '#';
n *= 2;
pos = 1, maxright = 0, ans = 0;
for(i = 1; i <= n; i++)
{
p[i] = 1;
if(i <= maxright)
p[i] = min(p[pos * 2 - i], maxright - i + 1);
while(s[i - p[i]] == s[i + p[i]]) p[i]++;
if(maxright < i + p[i] - 1)
{
pos = i;
maxright = i + p[i] - 1;
}
ans = max(ans, p[i] - 1);
}
printf("Case %d: %d\n", cnt, ans);
}
return 0;
}
[POJ3974]Palindrome(后缀数组 || manacher)的更多相关文章
- [bzoj3676]回文串[后缀数组+Manacher]
后缀数组+Manacher #include <iostream> #include <cstdio> #include <cstdlib> #include &l ...
- HDU - 3948 后缀数组+Manacher
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3948 题意:给定一个字符串,求字符串本质不同的回文子串个数. 思路:主要参考该篇解题报告 先按照man ...
- Trie树&kmp&AC自动机&后缀数组&Manacher
Trie 计数+Trie,读清题意很重要 https://vjudge.net/problem/UVALive-5913 kmp AC自动机 模板:https://vjudge.net/problem ...
- UVA - 11475 Extend to Palindrome (后缀数组)
Your task is, given an integer N, to make a palidrome (word that reads the same when you reverse it) ...
- URAL 1297 Palindrome 后缀数组
D - Palindrome Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- URAL - 1297 Palindrome —— 后缀数组 最长回文子串
题目链接:https://vjudge.net/problem/URAL-1297 1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB ...
- URAL 1297 Palindrome (后缀数组+RMQ)
题意:给定一个字符串,求一个最长的回回文子串,多解输出第一个. 析:把字符串翻转然后放到后面去,中间用另一个字符隔开,然后枚举每一个回文串的的位置,对第 i 个位置,那么对应着第二个串的最长公共前缀, ...
- Ural 1297 Palindrome(Manacher或者后缀数组+RMQ-ST)
1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The “U.S. Robots” HQ has just received a ...
- UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)
题目链接:点击打开链接 题意:给你一个串,让你在串后面添加尽可能少的字符使得这个串变成回文串. 思路:这题可以kmp,manacher,后缀数组三种方法都可以做,kmp和manacher效率较高,时间 ...
随机推荐
- 三、npm start报错:./node_modules/history/esm/history.js解决办法
package.json中的roadhog换为:'^2.5.0-beta.4',删除node_modules文件夹,在执行npm install,npm start.
- 点击按钮在表格的某一行下,在添加一行(HTML+JS)
使用js在指定的tr下添加一个新的一行newTr html代码: <table> <tr> <td>用户名:</td> <td><in ...
- shell脚本,awk在需要的行上打打印空行。
注解: 判断每行中是否包含字母a,包含了,就将$1的值赋值给变量a,然后判断变量a是否存在,存在打印一个空行,在将变量的值使用空变量b赋值,最后在打印输出. 结果就是在包含有字符a的行上打印一个空行.
- Linux运维笔记--第四部
第四部 3. Linux扩展正则表达式实战 扩展的正则表达式:ERE(主要用于egrep或grep -E) + 重复一个或一个以上前面的字符. (*是0或多个) ? 重复0个或一个 ...
- cocos2dx for lua A*寻路算法实现2
关于A*算法的实现过程,简单来说就是一个计算权限的过程. 首先,创建一个地图节点类,"MapNode.lua" local MapNode = class("MapNod ...
- Java-JFrame-swing嵌套浏览器步骤
Java-JFrame-swing嵌套浏览器步骤 一.使用swing嵌套浏览器要实现的功能: 通过java的swing实现在一个窗体中嵌套一个浏览器,可以在这个浏览器中将另一个项目的内容显示出来,只需 ...
- linux 上安装配置l2tp的客户端
有些时候我们外网linux服务器需要访问内网的服务器,这时候就需要在外网服务器上配置l2tp的客户端,连接到VPN访问内网服务器. 安装: yum -y install xl2tpd ppp 安装成功 ...
- 【全面】Linux基础知识和基本操作语句大全(一)
接触Linux已经有一段时间了,由于实际需要,三三两两地掌握了一些基本语法和实用语句,主要都是在日常开发中用得比较多的,条理不是特别清晰,请见谅!下面开始上硬货!! 基本操作: 关闭Linux系统的命 ...
- python基础-面向对象的三大特征
继承 单继承 父类 基类 子类 派生类 继承:是面向对象软件技术当中的一个概念,如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”. ...
- 用python编写简易登录接口
需求: 让用户输入用户名密码 认证成功后显示欢迎信息 输错三次后退出程序 可以支持多个用户登录 用户3次认证失败后,退出程序,再次启动程序尝试登陆时,还是锁定状态 下面是我写的代码,如果有BUG或者不 ...