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 [题目大意] 求最长回文子串,并输出这个串. [题解] 我们将原串倒置得到一个新的串,加一个拼接符将新 ...
随机推荐
- chrome debugger 调试
debugger 使用chrome调试时,html页面的js代码中可能不好打断点(因为在jvm中才会有代码) 我一开始是故意在需要断点的后面或前面写个错的alert,通过jvm找到此处,然后在需要的地 ...
- 【acl-访问控制列表】
配置acl访问控制列表{ firewall enable:开启路由器防火墙功能 fire default {permit || deny}:设置防火墙的默认行为: acl number[2000,29 ...
- (转)程序员新人怎样在复杂代码中找 bug?
我曾经做了两年大型软件的维护工作,那个项目有10多年了,大约3000万行以上的代码,参与过开发的有数千人,代码checkout出来有大约5个GB,而且bug特别多,open的有上千,即使最高优先级的s ...
- Apache httpd Server 配置正向代理
背景 代理(Proxy),位于客户端与实际服务端之间,当客户端需要请求服务端内容时,先向代理发起请求,代理将请求转发到实际的服务器,再原路返回.也可以在代理服务器设置缓存,将实际服务器上不常变化的内容 ...
- Hive优化之谓词下推
Hive优化之谓词下推 解释 Hive谓词下推(Predicate pushdown) 关系型数据库借鉴而来,关系型数据中谓词下推到外部数据库用以减少数据传输 基本思想:尽可能早的处理表达式 属于逻辑 ...
- 用pathon实现计算器功能
实现计算类似公式的计算器程序1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3* ...
- python2.7入门---SMTP发送邮件
SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式.python的smtplib提 ...
- VS2017 远程调试小记
VS2017 远程调试小记 支持windows\linux\macos, 直接连接项目点的上线版本代码进行调试.保证bug在同个环境下实时追踪. 注意点 双方的 msvsmon.exe版本需一致,最好 ...
- vi/vim 命令使用详解
1.Linux下创建文件 vi test.txt 或者 vim test.txt 或者 touch test.txt 2.vi/vim 使用 基本上 vi/vim 共分为三种模式,分别是命令模式(Co ...
- [模板]BZOJ4756线段树合并
题面 Solution: 板子不解释 #include <iostream> #include <algorithm> #include <cstdio> #inc ...