URAL 1297 Palindrome 最长回文子串
POJ上的,ZOJ上的OJ的最长回文子串数据量太大,用后缀数组的方法非常吃力,所以只能挑个数据量小点的试下,真要做可能还是得用manacher。贴一下代码
两个小错,一个是没弄懂string类的substr的用法是S.substr(i,len)从i开始的长度为len的一段。另外一个是RMQ的时候,询问rk[i],rk[j]的最长前缀应该是等效于求lcp[rk[i]] lcp[rk[j]-1]这一段,这个要在询问的时候注意一下。
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
#define maxn 1000050
using namespace std; int sa[maxn + 50];
int lcp[maxn + 50];
int rk[maxn + 50];
int tmp[maxn + 50];
int d[maxn + 50][25];
int n, k;
bool cmp_sa(int i, int j)
{
if (rk[i] != rk[j]) return rk[i] < rk[j];
else{
int ri = i + k <= n ? rk[i + k] : -1;
int rj = j + k <= n ? rk[j + k] : -1;
return ri < rj;
}
} void construct_sa(string S, int *sa)
{
n = S.length();
for (int i = 0; i <= n; i++){
sa[i] = i;
rk[i] = i < n ? S[i] : -1;
}
for (k = 1; k <= n; k <<= 1){
sort(sa, sa + n + 1, cmp_sa);
tmp[sa[0]] = 0;
for (int i = 1; i <= n; i++){
tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_sa(sa[i - 1], sa[i]) ? 1 : 0);
}
for (int i = 0; i <= n; i++){
rk[i] = tmp[i];
}
}
} void construct_lcp(string S, int *sa, int *lcp)
{
n = S.length();
for (int i = 0; i <= n; i++) rk[sa[i]] = i;
int h = 0;
lcp[0] = 0;
for (int i = 0; i < n; i++){
int j = sa[rk[i] - 1];
for (h ? h-- : 0; i + h < n&&j + h < n&&S[i + h] == S[j + h]; h++);
lcp[rk[i] - 1] = h;
}
} void construct_rmq(int *lcp,int sizen)
{
for (int i = 0; i <= sizen; i++) d[i][0] = lcp[i];
for (int j = 1; (1 << j) <= sizen; j++){
for (int i = 0; (i + (1 << j) - 1) <= sizen; i++){
d[i][j] = min(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
}
}
} int rmq_query(int l, int r)
{
if (l > r) swap(l, r); r -= 1;
int k = 0; int len = r - l + 1;
while ( (1 << (k + 1)) < len) k++;
return min(d[l][k], d[r - (1 << k) + 1][k]);
} string S;
string T; int main()
{
int ca = 0;
while (cin >> S)
{
if (S == "END") break;
int ctr = S.length();
T = S;
reverse(T.begin(), T.end());
S += '#' + T;
construct_sa(S, sa);
construct_lcp(S, sa, lcp);
construct_rmq(lcp, S.length() + 1);
int ans = 0;
string ansString;
int ansid;
int anstype;
for (int i = 0; i < ctr; i++){
int j = 2 * ctr - i;
int l = rmq_query(rk[i], rk[j]);
if (2 * l - 1>ans){
ans = 2 * l - 1;
ansid = i;
anstype = 0;
}
}
for (int i = 1; i < ctr; i++){
int j = 2 * ctr - i + 1;
int l = rmq_query(rk[i], rk[j]);
if (2 * l > ans){
ansid = i;
anstype = 1;
ans = 2 * l;
}
}
if (anstype == 0){
//ansString = S.substr(ansid-(ans-1)/2, ansid + (ans - 1) / 2);
for (int i = ansid - (ans - 1) / 2; i <= ansid + (ans - 1) / 2; i++){
cout << S[i];
}
cout << endl;
}
else{
//ansString = S.substr(ansid - ans / 2, ansid + ans / 2);
for (int i = ansid - ans/ 2; i <= ansid + ans/ 2-1; i++){
cout << S[i];
}
cout << endl;
}
}
return 0;
}
URAL 1297 Palindrome 最长回文子串的更多相关文章
- URAL 1297 求最长回文字符串
有种简单的方法,数组从左到右扫一遍,每次以当前的点为中心,只要左右相等就往左右走,这算出来的回文字符串是奇数长度的 还有偶数长度的回文字符串就是以当前扫到的点和它左边的点作为中心,然后往左右扫 这是O ...
- 【URAL 1297】Palindrome 最长回文子串
模板题,,,模板打错查了1h+QAQ #include<cmath> #include<cstdio> #include<cstring> #include< ...
- Ural 1297 Palindrome 【最长回文子串】
最长回文子串 相关资料: 1.暴力法 2.动态规划 3.中心扩展 4.Manacher法 http://blog.csdn.net/ywhorizen/article/details/6629268 ...
- Ural 1297 Palindrome(后缀数组+最长回文子串)
https://vjudge.net/problem/URAL-1297 题意: 求最长回文子串. 思路: 先将整个字符串反过来写在原字符串后面,中间需要用特殊字符隔开,那么只需要某两个后缀的最长公共 ...
- URAL 1297 最长回文子串(后缀数组)
1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB The “U.S. Robots” HQ has just received a ...
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...
- ural 1297 后缀数组 最长回文子串
https://vjudge.net/problem/URAL-1297 题意: 给出一个字符串求最长回文子串 代码: //论文题,把字符串反过来复制一遍到后边,中间用一个没出现的字符隔开,然后就是枚 ...
- Palindrome - POJ 3974 (最长回文子串,Manacher模板)
题意:就是求一个串的最长回文子串....输出长度. 直接上代码吧,没什么好分析的了. 代码如下: ================================================= ...
- POJ 3974 Palindrome(最长回文子串)
题目链接:http://poj.org/problem?id=3974 题意:求一给定字符串最长回文子串的长度 思路:直接套模板manacher算法 code: #include <cstdio ...
随机推荐
- [Guava源码分析]Ordering:排序
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3876466.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- 【OSG细节实现】节点围绕位于axisPos平行于axis的轴进行旋转
//绕着与axis平行的任意轴旋转 void rotate(const std::string& name, float angle, osg::Vec3 axisPos, osg::Vec3 ...
- 在Java中怎样把数组转换为ArrayList?
翻译自:How to Convert Array to ArrayList in Java? 本文分析了Stack Overflow上最热门的的一个问题的答案,提问者获得了很多声望点,使得他得到了在S ...
- SQL语句执行顺寻
SQL语句执行的时候是有一定顺序的.理解这个顺序对SQL的使用和学习有很大的帮助. 1.from 先选择一个表,或者说源头,构成一个结果集. 2.where 然后用where对结果集进行筛选.筛选出需 ...
- python 中range与xrange的区别
先来看看range与xrange的用法介绍 help(range)Help on built-in function range in module __builtin__: range(...) r ...
- ubuntu设置关闭屏幕和锁定
见链接:http://askubuntu.com/questions/177348/how-do-i-disable-the-screensaver-lock If you want to wrap ...
- PHP 如何判断当前用户已在别处登录
出处:http://bbs.lampbrother.net/read-htm-tid-121909-ds-1.html#tpc 主要思路:1.登录时,将用户的SessionID记录下来2.验证登录时, ...
- win32开发基础
收集的,正在学习... 跟我一起玩Win32开发(1):关于C++的几个要点 跟我一起玩Win32开发(2):完整的开发流程 跟我一起玩Win32开发(3):窗口的重绘 跟我一起玩Win32开发(4) ...
- AndroidSDK无法下载API包的解决方法
1:打开Android SDK Manager”,然后点击菜单栏中的“Tools”菜单选项,接下来只需选择“Options”选项即可打开设置窗体,在打开的选项中找到Others框,里面勾选第一个: F ...
- pyQuery
pyquery – PyQuery complete API 选择器基本支持jQuery用法 class pyquery.pyquery.PyQuery(*args, **kwargs) The ma ...