hdoj5371Hotaru's problem【Manacher】

来源:互联网 发布:网络课程运营 编辑:程序博客网 时间:2024/05/01 23:17

Hotaru's problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 3142    Accepted Submission(s): 1064


Problem Description
Hotaru Ichijou recently is addicated to math problems. Now she is playing with N-sequence.
Let's define N-sequence, which is composed with three parts and satisfied with the following condition:
1. the first part is the same as the thrid part,
2. the first part and the second part are symmetrical.
for example, the sequence 2,3,4,4,3,2,2,3,4 is a N-sequence, which the first part 2,3,4 is the same as the thrid part 2,3,4, the first part 2,3,4 and the second part 4,3,2 are symmetrical.

Give you n positive intergers, your task is to find the largest continuous sub-sequence, which is N-sequence.
 

Input
There are multiple test cases. The first line of input contains an integer T(T<=20), indicating the number of test cases. 

For each test case:

the first line of input contains a positive integer N(1<=N<=100000), the length of a given sequence

the second line includes N non-negative integers ,each interger is no larger than 109 , descripting a sequence.
 

Output
Each case contains only one line. Each line should start with “Case #i: ”,with i implying the case number, followed by a integer, the largest length of N-sequence.

We guarantee that the sum of all answers is less than 800000.
 

Sample Input
1102 3 4 4 3 2 2 3 4 4
 

Sample Output
Case #1: 9
 

Author
UESTC
 

Source
2015 Multi-University Training Contest 7
 

题意:给出一个序列从中选出一个序列满足将这个序列均分成三段前两段对称第一段和第三段相同问满足条件的序列的最长的长度。

解题思路:满足条件的序列满足前两段为回文字符串后两段也为回文字符串。第二段为共享的。所以只需要利用Manacher求出p数组枚举每个的回文串的长度逐个判断即可。

/* ***********************************************Author       : rycCreated Time : 2016-08-13 SaturdayFile Name    : E:\acm\hdoj\5371.cppLanguage     : c++Copyright 2016 ryc All Rights Reserved************************************************ */#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#include<list>#include<vector>#include<map>using namespace std;typedef long long LL;typedef pair<int,int>pii;const int maxn=100010;int num[maxn<<1];int p[maxn<<1];void Manacher(int len){    int mx=0,id=0;    for(int i=0;i<len;++i){        if(mx>i){            p[i]=min(p[2*id-i],mx-i);        }        else {            p[i]=1;        }        for(;i-p[i]>=0&&i+p[i]<len&&num[i+p[i]]==num[i-p[i]];p[i]++){            if(i+p[i]>mx){                mx=i+p[i];id=i;            }        }    }}int main(){    int t,n,T=1;cin>>t;    while(t--){        scanf("%d",&n);        int cnt=0,ans=0;num[cnt++]=-1;        for(int i=1;i<=n;++i){            scanf("%d",&num[cnt++]);num[cnt++]=-1;        }        memset(p,0,sizeof(p));        Manacher(cnt);        for(int i=0;i<cnt;i+=2){            for(int j=ans;j<p[i];j+=2){                if(p[i+j]>j)ans=j;            }        }        printf("Case #%d: %d\n",T++,ans/2*3);    }    return 0;}


0 0