题意:
给你一个字符串 s s s,找出最长的满足以下条件的字符串 s s s:
- 长度不超过 s s s
- s s s为回文字符串
- 存在两个字符串 a a a 和 b b b (可能为空), s = a + b s=a+b s=a+b( a a a 为 s s s 的前缀, a a a 为 s s s 的后缀)
先求出前缀和后缀,先把匹配的前后缀长度
t
t
t 求出来,然后由
t
−
1
t-1
t−1 开始从左向右匹配
h
a
s
h
hash
hash 值求最长的回文串,由
n
−
t
n-t
n−t 开始从左向右匹配
h
a
s
h
hash
hash 值求最长的回文串。
在
c
f
cf
cf 写
h
a
s
h
hash
hash 一定要注意
b
a
s
e
base
base 和
m
o
d
mod
mod ,不然特别容易被卡。
AC代码:
const int N = 1000100;
const ull P = 13131;
const int mod = 1000000007;
char s[N];
ull power[N];
ull pre[N], suf[N];
int ans, n;
int t, res, tmp;
ull hash1(int l, int r)
{
return (pre[r] - pre[l - 1] * power[r - l + 1] % mod + mod) % mod;
}
ull hash2(int l, int r)
{
return (suf[l] - suf[r + 1] * power[r - l + 1] % mod + mod) % mod;
}
void init()
{
power[0] = 1;
rep(i, 1, 1000000)
power[i] = power[i - 1] * P % mod;
}
int main()
{
init();
int T;
sd(T);
while (T--)
{
ans = 0;
ss(s + 1);
n = strlen(s + 1);
pre[0] = 0;
suf[n + 1] = 0;
rep(i, 1, n)
{
pre[i] = (pre[i - 1] * P + (s[i] - 'a' + 1)) % mod;
}
per(i, n, 1)
{
suf[i] = (suf[i + 1] * P + (s[i] - 'a' + 1)) % mod;
}
t = 0;
res = 0;
tmp = 0;
while (s[t + 1] == s[n - t] && t + 1 < n - t)
t++;
rep(i, t + 1, n - t)
{
if (hash1(t + 1, i) == hash2(t + 1, i) && i - t > res)
{
res = i - t;
tmp = 0;
}
}
per(i, n - t, t + 1)
{
if (hash1(i, n - t) == hash2(i, n - t) && n - t - i + 1 > res)
{
res = n - t - i + 1;
tmp = 1;
}
}
rep(i, 1, t)
{
cout << s[i];
}
if (tmp == 0)
{
rep(i, t + 1, t + res)
{
cout << s[i];
}
}
else
{
per(i, n - t, n - t - res + 1)
{
cout << s[i];
}
}
rep(i, n - t + 1, n)
{
cout << s[i];
}
cout << '\n';
}
return 0;
}