您的位置:首页 > 其它

hdu 3068 最长回文子串 manacher

2015-08-12 10:52 459 查看


最长回文

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 11393 Accepted Submission(s): 4112



Problem Description

给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.

回文就是正反读都是一样的字符串,如aba, abba等



Input

输入有多组case,不超过120组,每组输入为一行小写英文字符a,b,c...y,z组成的字符串S

两组case之间由空行隔开(该空行不用处理)

字符串长度len <= 110000



Output

每一行一个整数x,对应一组case,表示该组case的字符串中所包含的最长回文长度.



Sample Input

aaaa

abab




Sample Output

4
3




Source

2009 Multi-University Training
Contest 16 - Host by NIT



Recommend

lcy



#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n)  for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n)  for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n)  for(int i=(n) ;i>=0 ;i--)
#define  lson   num<<1,le,mid
#define rson    num<<1|1,mid+1,ri
#define MID   int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)

using namespace std;
const int INF =0x3f3f3f3f;
const int maxn= 110000+20   ;
//const int maxm=    ;
//const int INF=    ;
typedef long long ll;
const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
char s[maxn];
char tem[maxn<<1];
int nex[maxn<<1];
int L;
void install()
{
    tem[0]='$';   //最左边加上'$'是为了防止出界,因为字符串中一般没有字符能和'$'匹配,
    //字符串末尾的'\0'也是同样效果,而且必须加'\0';
    int i=0,dp=0,k=1;
    while(s[i])
    {
        tem[k++]=  dp?s[i++]:'#';  //小技巧
        dp^=1;
    }
    tem[k++]='#';
    tem[L=k]='\0';            
}

void getnex()
{
    int far=0,id;
     for(int i=1;i<L;i++)
    {  //2*id就是以id为对称中心且0为最左点的最右点,减去i,那么就是i关于id的对成点,简单说就是中点公式
        if(far>i)  nex[i]=min(far-i,nex[ 2*id-i]);//开始的点最大为far-i,用min定义了一个上限
        else nex[i]=1;
        for(  ; tem[i-nex[i]]==tem[i+nex[i]]  ;nex[i]++ )
        if(far<i+nex[i])    far=i+nex[i],id=i;
    }
}
int main()
{
  while(~scanf("%s",s))
  {
      install();
      getnex();
      int maxi=0;
      for(int i=1;i<L;i++)
        maxi=max(maxi,nex[i]-1);   //为什么是nex[i]-i;-可以这样想,
        //首先考虑tem[i]是否是'#',然后从i不断延伸,总是停在一 个'#'上,有成对性。
    printf("%d\n",maxi);
  }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: