Ural 1297 Palindrome(Manacher或者后缀数组+RMQ-ST)
1297. Palindrome
Memory limit: 64 MB
service would have already started an undercover operation to establish the agent’s identity, but, fortunately, the letter describes communication channel the agent uses. He will publish articles containing stolen data to the “Solaris” almanac. Obviously,
he will obfuscate the data, so “Robots Unlimited” will have to use a special descrambler (“Robots Unlimited” part number NPRx8086, specifications are kept secret).
by “Robots Unlimited”. Unfortunately, he was fired just before his team has finished work on the NPRx8086 design.
a haystack. However, after he struggled the problem for a while, he remembered that the design of NPRx8086 was still incomplete. “Robots Unlimited” fired John when he was working on a specific module, the text direction detector. Nobody else could finish that
module, so the descrambler will choose the text scanning direction at random. To ensure the correct descrambling of the message by NPRx8086, agent must encode the information in such a way that the resulting secret message reads the same both forwards and
backwards.
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.
text before feeding it into the program.
Input
Output
Sample
| input | output |
|---|---|
ThesampletextthatcouldbereadedthesameinbothordersArozaupalanalapuazorA |
ArozaupalanalapuazorA |
Manacher模版题,但是学习到如何输出对应的回文串,即开始坐标=(id-p[id]+1)>>1
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long LL;
const int N = 1010;
char s[N], ss[2 * N];
int p[2 * N];
inline int manacher(char s[])
{
int mx = p[0] = 0, idd, len = strlen(s), S = 0, L = 0;
for (int i = 1; i < len; i++)
{
p[i] = 1;
if (mx > i)
{
p[i] = p[2 * idd - i];
if (mx - i < p[i])
p[i] = mx - i;
}
while (s[i - p[i]] == s[i + p[i]])
p[i]++;
if (i + p[i] > mx)
{
mx = i + p[i];
idd = i;
if (p[i] > S)
S = p[i];
}
}
return S;
}
int main(void)
{
int i, j;
while (~scanf("%s", s))
{
ss[0] = '$';
int len = strlen(s);
for (i = 0; i < len; i++)
{
ss[2 * i + 1] = '#';
ss[2 * i + 2] = s[i];
}
ss[2 * len + 1] = '#';
int LEN = manacher(ss) - 1;
int idd = 0;
for (i = 1; i < 2 * len + 1; i++)
{
if (p[i] > p[idd])
idd = i;
}
int cnt = 0;
for (i = (idd - p[idd] + 1) >> 1; cnt < LEN; i++, cnt++)
putchar(s[i]);
putchar('\n');
MM(s);
MM(ss);
MM(p);
}
return 0;
}
玩了下后缀数组,调了半天终于调出来了,注意一些区间合法判断就好了
代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 2010;
int wa[N], wb[N], cnt[N], sa[N];
int ran[N], height[N];
char s[N]; inline int cmp(int r[], int a, int b, int d)
{
return r[a] == r[b] && r[a + d] == r[b + d];
}
void DA(int n, int m)
{
int i;
int *x = wa, *y = wb;
for (i = 0; i < m; ++i)
cnt[i] = 0;
for (i = 0; i < n; ++i)
++cnt[x[i] = s[i]];
for (i = 1; i < m; ++i)
cnt[i] += cnt[i - 1];
for (i = n - 1; i >= 0; --i)
sa[--cnt[x[i]]] = i;
for (int k = 1; k <= n; k <<= 1)
{
int p = 0;
for (i = n - k; i < n; ++i)
y[p++] = i;
for (i = 0; i < n; ++i)
if (sa[i] >= k)
y[p++] = sa[i] - k;
for (i = 0; i < m; ++i)
cnt[i] = 0;
for (i = 0; i < n; ++i)
++cnt[x[y[i]]];
for (i = 1; i < m; ++i)
cnt[i] += cnt[i - 1];
for (i = n - 1; i >= 0; --i)
sa[--cnt[x[y[i]]]] = y[i];
swap(x, y);
x[sa[0]] = 0;
p = 1;
for (i = 1; i < n; ++i)
x[sa[i]] = cmp(y, sa[i - 1], sa[i], k) ? p - 1 : p++;
m = p;
if (m >= n)
break;
}
}
void gethgt(int n)
{
int i, k = 0;
for (i = 1; i <= n; ++i)
ran[sa[i]] = i;
for (i = 0; i < n; ++i)
{
if (k)
--k;
int j = sa[ran[i] - 1];
while (s[j + k] == s[i + k])
++k;
height[ran[i]] = k;
}
}
namespace SG
{
int dp[N][12];
void init(int l, int r)
{
int i, j;
for (i = l; i <= r; ++i)
dp[i][0] = height[i];
for (j = 1; l + (1 << j) - 1 <= r; ++j)
{
for (i = l; i + (1 << j) - 1 <= r; ++i)
dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
}
int ask(int l, int r)
{
int len = r - l + 1;
int k = 0;
while (1 << (k + 1) <= len)
++k;
return min(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int LCP(int l, int r, int len)
{
if (l > r)
swap(l, r);
if (l == r)
return len - sa[l];
return ask(l + 1, r);
}
}
int main(void)
{
int i;
while (~scanf("%s", s))
{
int len = strlen(s);
s[len] = '$';
for (i = 0; i < len; ++i)
s[len + i + 1] = s[len - 1 - i];
int nlen = len << 1 | 1;
s[nlen] = '\0';
DA(nlen + 1, 'z' + 1);
gethgt(nlen);
SG::init(1, nlen);
int ans = 1;
int pos = 0;
for (i = 0; i < len; ++i)
{
int lcp = SG::LCP(ran[i], ran[nlen - i - 1], len);//奇数
int Ans = lcp * 2 - 1;
if (Ans > ans || (Ans == ans && i - lcp + 1 < pos))
{
ans = Ans;
pos = i - lcp + 1;
} lcp = SG::LCP(ran[i], ran[nlen - i], len);//偶数
Ans = lcp * 2;
if (Ans > ans || (Ans == ans && i - lcp < pos))
{
ans = Ans;
pos = i - lcp;
}
}
for (int i = pos; i < pos + ans; ++i)
putchar(s[i]);
puts("");
}
return 0;
}
Ural 1297 Palindrome(Manacher或者后缀数组+RMQ-ST)的更多相关文章
- ural 1297 Palindrome(Manacher模板题)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 求最长回文子串. http://acm.timus.ru/problem.aspx ...
- 1297. Palindrome ural1297(后缀数组)
1297. Palindrome Time limit: 1.0 secondMemory limit: 64 MB The “U.S. Robots” HQ has just received a ...
- 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过
题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...
- POJ 3693 后缀数组+RMQ
思路: 论文题 后缀数组&RMQ 有一些题解写得很繁 //By SiriusRen #include <cmath> #include <cstdio> #includ ...
- spoj687 REPEATS - Repeats (后缀数组+rmq)
A string s is called an (k,l)-repeat if s is obtained by concatenating k>=1 times some seed strin ...
- URAL 题目1297. Palindrome(后缀数组+RMQ求最长回文子串)
1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The "U.S. Robots" HQ has just ...
- URAL 1297 Palindrome 后缀数组
D - Palindrome Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Subm ...
- 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome
题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...
- URAL 1297 Palindrome(后缀数组+ST表)
[题目链接] http://acm.timus.ru/problem.aspx?num=1297 [题目大意] 求最长回文子串,并输出这个串. [题解] 我们将原串倒置得到一个新的串,加一个拼接符将新 ...
随机推荐
- Cacti 学习笔记
Cacti是用php语言实现的一个软件,它的主要功能是用snmp服务获取数据,然后用rrdtool储存和更新数据,当用户需要查看数据的时候用rrdtool生成图表呈现给用户.因此,snmp和rrdto ...
- 介绍几个PHP 自带的加密解密函数
PHP 自带的加密解密函数 目前经常使用的加密函数有:md5(), sha1(), crypt(), base64_encode(), urlencode() . 其中 md5(), sha1(), ...
- python应用:主题分类(gensim lda)
安装第三方包:gensim 首先,执行去停词操作(去除与主题无关的词) #-*-coding:utf8-*- import jieba def stopwordslist(filepath): sto ...
- kivy学习三:打包成window可执行文件
根据官方文档写出如下内容,主要是为了记录自己遇到的坑! 一.打开命令行 1.win+r 2.输入CMD(没错,就是那个黑窗口就是命令行) 二.新建一个新文件夹,用来存放我们打包成的文件(这里一定要注意 ...
- web视频播放
webm.mp4/h264 video.js hevc libde265.js hls/m3u8 hls.js
- 【Android开发】 HttpURLConnection.getOutputStream() IO异常
HttpURLConnection.getOutputStream() IO异常百度下,没找到想要的答案.网上的解决方案几乎都是从权限考虑的~最后找到个国外网站上找到答案~ http://stack ...
- Spring 框架控制器类方法可用的参数与返回类型
参数类型 Spring 有内建的 HTTP 消息转换器用于部分简单类型之间的转换 标准 Servlet 类型:HttpServletRequest, HttpServletResponse, Http ...
- P1346 电车(dijkstra)
P1346 电车 题目描述 在一个神奇的小镇上有着一个特别的电车网络,它由一些路口和轨道组成,每个路口都连接着若干个轨道,每个轨道都通向一个路口(不排除有的观光轨道转一圈后返回路口的可能).在每个路口 ...
- os模块3
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录:相当于shell下cd os.curd ...
- linux里面的fork函数创建一个新进程
由fork创建的新进程成为子进程,fork函数被调用一次,但是返回两次,