UVA12467「Secret Word」

1. 题目

题目链接:UVA12467「Secret Word」

Description

Alicia and Roberto like to play games. Today, Roberto is trying to guess a secret word that Alicia chose. Alicia wrote a long string SS in a piece of paper and gave Roberto the following clues:

  • The secret word is a non-empty substring (A substring of SS is defined as any consecutive sequence of characters belonging to SS. For example, if SS = abcd then a, abcd, ab, bc and bcd are some of the substrings of SS but ac, aa, aabbccdd and dcba are not substrings of SS) of SS (possibly equal to SS).
  • SS starts with the secret word reversed.

Roberto knows Alicia very well, and he’s sure that if there are several possible secret words that satisfy the clues above, Alicia must have chosen the longest one.

Can you help him guess the secret word?

Input

The first line of the input file contains a single integer number T150T \leq 150, the number of test cases.

TT lines follow, each with a single string SS. SS will only contain lowercase English letters. The length of SS will not exceed one million characters.

Output

For each test case, output the secret word in one line.

Explanation of the sample cases:

  • colombia: if you take c and reverse it you get c. colombia starts with c, so this satisfies the two clues above. Furthermore, c is the longest word that satisfies the two clues so it must be the secret word.
  • abcdba: if you take ba and reverse it you get ab. abcdba starts with ab and there’s no longer substring that satisfies the two clues.
  • neversayeven: if you take even and reverse it you get neve. neversayeven starts with neve and there’s no longer substring that satisfies the two clues.
  • neveroddoreven: this case is a palindrome so if we reverse it we get the same string. neveroddoreven starts with neveroddoreven (since they are the same) and obviously there’s no longer substring that satisfies that, so this is the secret word.
  • listentothesilence: Notice the secret word might be somewhere in the middle of the big word.

Sample Input

1
2
3
4
5
6
5
colombia
abcdba
neversayeven
neveroddoreven
listentothesilence

Sample Output

1
2
3
4
5
c
ba
even
neveroddoreven
sil

2. 题目

2.1 分析

  • 由题意可知,最终的 secret 满足 secret 和 secret 的反转 secret' 均在字符串 ss 中。将字符串 ss 反转后的得到 ss',然后将 ssss' 拼接在一起得到 S=s+#+sS = s + \# + s',在对 SS 求前缀函数。然后统计 π[n+1..2n]\pi[n+1..2n] 中最大的,此即为满足题意的最长 secret 的长度,设对应下标为 pospos
  • 由于 ssss' 关于下标 x=nx = n 对称,故最终答案为 s[2npos..2npos+π[pos]1]s[2n-pos..2n-pos+\pi[pos]-1]

2.2 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <bits/stdc++.h>
using namespace std;

// 前缀函数
struct PrefixFunction {
#ifndef _PREFIXFUNCTION_
#define ll int
#define MAXN 2000005
#endif
ll pi[MAXN]; // 前缀函数
PrefixFunction() {}
// 计算前缀函数
void getPi(char *str, ll n) {
pi[0] = 0;
ll i = 1, j = pi[i-1];
while(i < n) {
if(str[i] == str[j]) {
pi[i++] = j++ + 1;
} else if(!j) {
pi[i++] = j;
} else {
j = pi[j-1];
}
}
}
};

int main()
{
static char str[MAXN];
static PrefixFunction pf;
ll t;
scanf("%d", &t);
for(ll k = 0; k < t; ++k) {
scanf("%s", str);
ll n = strlen(str);
for(ll i = 0, j = n-1; ~j; --j,++i) {
str[n+1+i] = str[j];
}
pf.getPi(str, 2*n+1);
ll ans = 0, pos;
for(ll i = n+1; i < 2*n+1; ++i) {
if(pf.pi[i] > ans) {
ans = pf.pi[i];
pos = i;
}
}
str[2*n-pos+ans] = '\0';
printf("%s\n", &str[2*n-pos]);
}
return 0;
}