题意:
给你一系列数,求出最长的回文数列,且回文数列是从对称点往两端不递增。输出数列的最大长度。
思路:
manacher算法求最长回文数列,但要特判从对称点往两端不递增。
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 1e6 + 5;
int s[maxn], t[maxn * 2];
int lengh[maxn * 2];
int manacher(int n){
int len = n;
t[0] = -1;
int cot = 0;
for(int i = 0; i < len; i++){
t[++cot] = 0;
t[++cot] = s[i];
}
t[++cot] = 0;
t[++cot] = -2;
int p = 0, mx = 0;
lengh[0] = 0;
for(int i = 1; i < cot; i++){
if(p + lengh[p] > i) lengh[i] = min(p + lengh[p] - i, lengh[p * 2 - i]);
else lengh[i] = 1;
while(t[i + lengh[i]] == t[i - lengh[i]]) {
if(t[i + lengh[i]] != 0 && t[i - lengh[i] + 2] < t[i - lengh[i]]) break;
lengh[i]++;
}
if(p + lengh[p] < i + lengh[i]) p = i;
mx = max(mx, lengh[i]);
}
return mx - 1;
}
int main(){
int T, n;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &s[i]);
printf("%d\n", manacher(n));
}
}