Description 吉哥又想出了一个新的完美队形游戏! Input 输入数据第一行包含一个整数T,表示总共有T组测试数据(T <= 20); Output 请输出能组成完美队形的最多人数,每组输出占一行。 Sample Input
Sample Output
|
不同于普通最长回文子串,这题需要满足回文子串前半段递增。
先忽略这个特殊条件,用Manacher算法求出每个字符为中心的最长子串,最后再循环判断这个条件。
#include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<set> #include<algorithm> using namespace std; int s[200005]; int ans[200005]; int change_str(int *s,int len) { int j=len-1; for(int i=len*2+1; i>=1; i-=2) { s[i] = -1; s[i-1] = s[j]; j--; } s[0] = -2; return len*2+2; } int main() { int T; scanf("%d",&T); while(T--) { int len; scanf("%d",&len); for(int i=0;i<len;i++) scanf("%d",&s[i]); len = change_str(s,len); int mx=0,id=0; ans[0]=1; for(int i=1; i<len; i++) { int r=i+ans[id-(i-id)] , l=i-ans[id-(i-id)]; if(r>mx) { r=max(mx+1,i+1); l=i-(r-i); while(s[l]==s[r]) { l--; r++; } mx = r-1; id = i; } ans[i] = r-i; } mx = 1; int pre=0; for(int i=2; i+2<len; i+=2) { //printf("%d ",pre); mx = max(mx,min(ans[i]-1,(i-pre)+1)); mx = max(mx,min(ans[i+1]-1,(i+1-pre)+1)); if(s[i]>s[i+2]) pre=i+1; } printf("%d ",mx); } }