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 [题目大意] 求最长回文子串,并输出这个串. [题解] 我们将原串倒置得到一个新的串,加一个拼接符将新 ...
随机推荐
- dom技术解析xml (php)
1.xml实例 test.xml <?xml version="1.0" encoding="utf-8"?><!DOCTYPE 班级 SYS ...
- Angular : 绑定, 参数传递, 路由
如何把jquery导入angular npm install jquery --savenpm install @type/jquery --save-dev "node_modules/z ...
- Java基础——继承和多态
面向对象的编程允许从已经存在的类中定义新的类,这称为继承. 面向过程的范式重点在于方法的设计,而面向对象的范式将数据和方法结合在对象中.面向对象范式的软件设计着重于对象以及对象上的操作.面向对象的方法 ...
- python学习之面向对象程序设计的一些思考
将属于一类的对象放在一起: 如果一个函数操纵一个全局变量,那么两者最好都在类内作为特性和方法实现. 不要让对象过于亲密: 方法应该只关心自己实例的特性,让其他实例管理自己的状态. 简单就好: 让方法小 ...
- PHP教程专题资源免费下载地址收藏
PHP教程专题资源免费下载地址收藏 PHP,即Hypertext Preprocessor,是一种被广泛应用的开源通用脚本语言,尤其适用于 Web 开发并可嵌入 HTML 中去.它的语法利用了 C. ...
- FZU:1759-Problem 1759 Super A^B mod C (欧拉降幂)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=1759 欧拉降幂是用来干啥的?例如一个问题AB mod c,当B特别大的时候int或者longlong装不下的时 ...
- python 推导式的用法
推导式看了不少,可每次都有新发现 例子1:返回满足条件为真,否则为假 try_list = [1, 2, 3, 4, 5] # 前2种一样, [a > 3 for a in b] [True i ...
- P1095 守望者的逃离
P1095 守望者的逃离 题目描述 恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变.守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上.为了杀死守望者,尤迪安开始对这 ...
- cmd中可以运行java,但不能运行javac命令
在cmd中可以运行java,但运行javac命令时提示:'javac' 不是内部或外部命令,也不是可运行的程序或批处理文件. 原因:安装java时把jdk的路径和jre的路径选择成一样,就造成覆盖了. ...
- React16版本的新特性
React16版本更新的新特性 2018年05月03日 21:27:56 阅读数:188 1.render方法的返回值类型:New render return types 之前的方式: class A ...