http://acm.uestc.edu.cn/bbs/simple/?t3258.html
给一个序列,让求其最大子序列
这个序列由三段组成,第一段和第二段对称,第一段和第三段一样
manacher算法求得p[i]
枚举第二段的起点和长度,得到结果
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <climits>
#include <ctime>
using namespace std;
#define INF 0x3f3f3f3f;
#define PI cos(-1.0);
const int maxn=100010;
int p[maxn*2];
int a[maxn*2];
void Manacher(int n)
{
memset(p,0,sizeof(p));
int i;
int mx=0;
int id=0;
for(int i=1;i<n;i++)
{
if(mx>i)
p[i]=min(p[2*id-i],mx-i);
else
p[i]=1;
for(;a[i+p[i]]==a[i-p[i]];p[i]++);
if(p[i]+i>mx)
{
mx=p[i]+i;
id=i;
}
}
}
int main()
{
int T,kase=1;
scanf("%d",&T);
while(T--)
{
int n;
memset(a,0,sizeof(a));
a[0]=-1;
scanf("%d",&n);
int len=1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[len++]);
a[len++]=-1;
}
int max_len=1;
Manacher(len);
for(int i=2;i<len-1;i+=2)
{
for(int j=max_len;j<=p[i];j+=2)
{
if(p[i+j-1]>=j)max_len=j;
}
}
max_len=max_len/2*3;
printf("Case #%d: %d\n",kase++,max_len);
}
return 0;
}