URAL 1297 最长回文子串(后缀数组)
1297. Palindrome
Memory limit: 64 MB
In addition, it is reasonable to assume that the agent will be sending a very long message, so John has simply to find the longest message satisfying the mentioned property.
Input
Output
Sample
| input |
|---|
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA |
| output |
ArozaupalanalapuazorA |
/*
URAL 1297 最长回文子串(后缀数组) 算法合集之《后缀数组——处理字符串的有力工具》:
穷举每一位,然后计算以这个字符为中心的最长回文子串。注意这里要分两
种情况,一是回文子串的长度为奇数,二是长度为偶数。两种情况都可以转化为
求一个后缀和一个反过来写的后缀的最长公共前缀。具体的做法是:将整个字符
串反过来写在原字符串后面,中间用一个特殊的字符隔开。这样就把问题变为了
求这个新的字符串的某两个后缀的最长公共前缀。 所以我们只需先对初始的字符串进行一下处理,然后分别进行奇偶判断得到
最长回文子串的位置和长度 hhh-2016-03-13 15:41:30
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>
using namespace std;
typedef long long ll;
typedef long double ld;
#define lson (i<<1)
#define rson ((i<<1)|1)
const int maxn = 5005; int t1[maxn],t2[maxn],c[maxn];
bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b] &&r[l+a] == r[l+b];
} void get_sa(int str[],int sa[],int Rank[],int height[],int n,int m)
{
n++;
int p,*x=t1,*y=t2;
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[i] = str[i]]++;
for(int i = 1; i < m; i++) c[i] += c[i-1];
for(int i = n-1; i>=0; i--) sa[--c[x[i]]] = i;
for(int j = 1; j <= n; j <<= 1)
{
p = 0;
for(int i = n-j; i < n; i++) y[p++] = i;
for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;
for(int i = 0; i < m; i++) c[i] = 0;
for(int i = 0; i < n; i++) c[x[y[i]]]++ ;
for(int i = 1; i < m; i++) c[i] += c[i-1];
for(int i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y);
p = 1;
x[sa[0]] = 0;
for(int i = 1; i < n; i++)
x[sa[i]] = cmp(y,sa[i-1],sa[i],j)? p-1:p++;
if(p >= n) break;
m = p;
}
int k = 0;
n--;
for(int i = 0; i <= n; i++)
Rank[sa[i]] = i;
for(int i = 0; i < n; i++)
{
if(k) k--;
int j = sa[Rank[i]-1];
while(str[i+k] == str[j+k]) k++;
height[Rank[i]] = k;
}
} int mm[maxn];
int dp[20][maxn];
int Rank[maxn],height[maxn];
int sa[maxn],str[maxn];
char ts[maxn]; void ini_RMQ(int n)
{
mm[0] = -1;
for(int i = 1;i <= n;i++)
mm[i] = (((i & (i-1)) == 0) ? mm[i-1]+1:mm[i-1]); for(int i =1;i <= n;i++)
dp[0][i] = height[i];
for(int i = 1;i <= mm[n];i++)
{
for(int j = 1;j+(1<<i)-1 <= n;j++)
{
int a = dp[i-1][j];
int b = dp[i-1][j+(1<<(i-1))];
dp[i][j] = min(a,b);
}
}
} int askRMQ(int a,int b)
{
int t = mm[b-a+1];
b -= (1<<t)-1;
return min(dp[t][a],dp[t][b]);
} int fin(int a,int b)
{
a = Rank[a],b = Rank[b];
if(a > b) swap(a,b);
return askRMQ(a+1,b);
} int main()
{
while(scanf("%s",ts) != EOF)
{
int len = strlen(ts);
for(int i = 0;i < len;i++)
str[i] = ts[i];
str[len] = 1;
for(int i = 0;i < len;i++)
str[i+len+1] = ts[len-i-1];
str[len*2+1] = 0; get_sa(str,sa,Rank,height,2*len+1,128);
ini_RMQ(2*len+1); int ans = 0,pos;
int tp;
for(int i = 0;i < len;i++)
{
tp = fin(i,len*2+1-i);
if(tp*2 > ans)
{
ans = tp*2;
pos = i-tp;
}
tp = fin(i,len*2-i);
if(tp*2-1 > ans)
{
ans = tp*2-1;
pos = i-tp+1;
}
}
ts[pos+ans] = 0;
printf("%s\n",ts+pos);
}
return 0;
}
URAL 1297 最长回文子串(后缀数组)的更多相关文章
- Ural1297 最长回文子串(后缀数组+RMQ)
/* 源程序丢失QWQ. 就不粘代码了. 大体做法是把串反转然后连接. 做一遍后缀数组. 对height做一遍rmq. 然后对于每个位置的奇偶分别判断, 记下pos. 注意求的是[l+1,r]的hei ...
- ural1297 求最长回文子串 | 后缀数组
#include<cstdio> #include<algorithm> #include<cstring> #define N 20005 using names ...
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...
- Ural 1297 Palindrome(后缀数组+最长回文子串)
https://vjudge.net/problem/URAL-1297 题意: 求最长回文子串. 思路: 先将整个字符串反过来写在原字符串后面,中间需要用特殊字符隔开,那么只需要某两个后缀的最长公共 ...
- ural 1297 后缀数组 最长回文子串
https://vjudge.net/problem/URAL-1297 题意: 给出一个字符串求最长回文子串 代码: //论文题,把字符串反过来复制一遍到后边,中间用一个没出现的字符隔开,然后就是枚 ...
- URAL 1297 Palindrome 最长回文子串
POJ上的,ZOJ上的OJ的最长回文子串数据量太大,用后缀数组的方法非常吃力,所以只能挑个数据量小点的试下,真要做可能还是得用manacher.贴一下代码 两个小错,一个是没弄懂string类的sub ...
- Ural 1297 Palindrome 【最长回文子串】
最长回文子串 相关资料: 1.暴力法 2.动态规划 3.中心扩展 4.Manacher法 http://blog.csdn.net/ywhorizen/article/details/6629268 ...
- [译+改]最长回文子串(Longest Palindromic Substring) Part II
[译+改]最长回文子串(Longest Palindromic Substring) Part II 原文链接在http://leetcode.com/2011/11/longest-palindro ...
- 【转】最长回文子串的O(n)的Manacher算法
Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...
随机推荐
- js日常积累
1.数组转字符串 str.join(',') 2.字符串转数组 arr.split(',') 3.数组排序 function sorb(a,b){return a-b;}; arr.sort(sorb ...
- Linux 目录与文件管理
1. 目录与路径1.1 相对路径与绝对路径1.2 目录的相关操作: cd, pwd, mkdir, rmdir1.3 关于执行文件路径的变量: $PATH2. 档案与目录管理2.1 档案与目录的检视: ...
- 十、Python练习----基础搭建飞机大战
只是简单的学习了pygame,实现飞机的摧毁还需要多张图片的切换,和sprite(碰撞精灵),还有多种音效的添加(如背景音乐.摧毁特效).以后再深入学习我只是练习一下python. 一.搭建界面(基于 ...
- django的FBV和CBV
title: python djano CBV FBV tags: python, djano, CBV, FBV grammar_cjkRuby: true --- python django的fu ...
- LeetCode & Q121-Best Time to Buy and Sell Stock-Easy
Array DP Description: Say you have an array for which the ith element is the price of a given stock ...
- ssl双向认证
ssl双向认证 一.背景知识 1.名词解释 ca.key: 根证书的私钥 , ca.crt: 根证书的签名证书 server.key, server.crt client.key, client.cr ...
- JWT
Web安全通讯之Token与JWT http://blog.csdn.net/wangcantian/article/details/74199762 javaweb多说本地身份说明(JWT)之小白技 ...
- 租户、租户管理员、部门管理员和开发者在APIGW中的角色
一.参与者 1.vdcId:租户 2.运营管理员 operator: 一种角色 创建开发商 审批外置服务,如:hadoop集群 审批内置服务,如:<API使用申请> 3.租户管理员 ...
- CentOS7 安装eclipse
1. 首先将eclipse的压缩包文件解压到/opt目录下,要使用root权限.执行如下解压命令:tar -zxvf eclipse-jee-oxygen-1a-linux-gtk-x86_64.ta ...
- MySQL5.7.21解压版安装详细教程以及一些问题的解决
笔者是最近玩mysql的时候玩坏了,想写点东西记录下.我安装的是MySQL5.7.21,安装之后没有my.ini文件. 遇到了2个问题,一是mysql服务启动不了,被my.ini整了,二是root密码 ...