hdu5371 Hotaru's problem manachar回文串算法+枚举

来源:互联网 发布:java 超级打码 编辑:程序博客网 时间:2024/05/16 17:53
Hotaru's problem**Time Limit: 4000/2000 MS (Java/Others)    **Memory Limit:**** 65536/65536 K (Java/Others)****Total Submission(s): 1806    Accepted Submission(s): 648****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.>InputThere 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.>OutputEach 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 Input1102 3 4 4 3 2 2 3 4 4Sample OutputCase #1: 9**Source****2015 Multi-University Training Contest 7** 

不会的可以看下面的
浅谈manacher算法
道理是一样的,只不过因为是偶数的回文串所以直接跳过避过奇偶的插入

#include <cstdio>#include <cstring>#include <set>#include <queue>#include <iostream>#include <algorithm>using namespace std;const int N=100005;typedef pair<int,int> pa;int a[N];int p[N];int main(){    int T;    scanf("%d",&T);    for(int cas=1;cas<=T;cas++)    {        int n;        memset(p,0,sizeof p);        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%d",&a[i]);        int id=0,maxn=0;        for(int i=1;i<=n;i++)        {            if(p[id]+id>i+1){                p[i]=min(p[id*2-i],p[id]+id-i-1);            }            else                p[i]=1;            while(i+p[i]<=n && i+1-p[i]>=1 && a[i+p[i]]==a[i+1-p[i]]){                  p[i]++;              }            if(p[i]+i>p[id]+id)                id=i;        }        for(int i=1;i<=n;i++){            p[i]=p[i]-1;        }        int mx=0;        int tt;        for(int i=1;i<=n;i++){            if(mx<p[i]){                tt=p[i];                while(tt>mx && p[i+tt]<tt)                  tt--;                  mx=max(mx,tt);             }        }         printf("Case #%d: %d\n",cas,3*mx);    }}/*100219 8 0 0 8 9 9 8 0 8 9 9 8 0 8 9 9 8 0 8 9*/
0 0