[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效率较高,时间 ...
随机推荐
- Firefox火狐广告过滤插件Adblock Plus过滤规则包[中文维护小组]
如果你经常使用Firefox火狐浏览器那么一定知道Adblock Plus这款广告过滤插件,功能非常强大,但是Adblock Plus广告过滤插件自带的过滤规则并不多,而且也不太适合我们中国的网站,在 ...
- UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
摘要:中途相遇.对比map,快排+二分查找,Hash效率. n是4000的级别,直接O(n^4)肯定超,所以中途相遇法,O(n^2)的时间枚举其中两个的和,O(n^2)的时间枚举其他两个的和的相反数, ...
- Android(java)学习笔记130:Android中操作XML数据(使用Pull解析器)
1. Pull解析器的运行方式与 SAX 解析器相似.它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件.跟SAX不同的是, Pull解析器 ...
- IOS CoreData 多表查询(下)
http://blog.csdn.net/fengsh998/article/details/8123392 在iOS CoreData中,多表查询上相对来说,没有SQL直观,但COREDATA的功能 ...
- CentOS7练习
为编译安装的httpd服务,实现service unit文件破解centos7 口令修改默认的启动内核为新编译内核启动时临时禁用SELinux启动时进入emergency模式卸载编译安装的新内核
- ccf 201712-2 游戏(Python实现)
一.原题 问题描述 试题编号: 201712-2 试题名称: 游戏 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐 ...
- 数字内置方法详解(int/long/float/complex)
一.常用方法 1.1.int 以下是Python2.7的int内置函数: 序号 函数名 作用 举例 1 int.bit_length() 二进制存储这个整数至少需要多少bit(位). >> ...
- nginx作为正向代理,反向代理的一些应用
正向代理代理的对象是客户端 反向代理代理的对象是服务端 举例说下nginx作为正向代理作访问控制 server{ listen 80; server_name localhost jeson.gaos ...
- LeetCode(283)Move Zeroes
题目 Given an array nums, write a function to move all 0's to the end of it while maintaining the rela ...
- 【HIHOCODER 1420】 Bigint Multiplication
描述 Given 2 nonnegative integers a and b, calculate a × b. 输入 One line with 2 integers a and b separa ...