回文子串的最大长度

题目:回文子串的最大长度

思想:字符串哈希+二分 OR Manacher
代码1:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2001000;//注意数组开的范围
typedef unsigned long long ULL;
char s[maxn];
ULL hr[maxn], hl[maxn], p[maxn];
int base = 131;
ULL query(ULL h[], int l, int r)
{
    return h[r] - h[l-1]*p[r-l+1];
}
int main()
{
    int ca = 0;
    while(scanf("%s", s+1) && strcmp(s+1, "END"))
    {
        int n = strlen(s+1);
        n *= 2;
        for(int i =  n; i > 0; i -= 2) //强行在数组中加入新的辅助符号
        {
            s[i] = s[i/2];
            s[i-1] = 'z'+1;
        }
        p[0] = 1;
        for(int i = 1, j = n; i <= n; i++, j--) //字符串哈希
        {
            hl[i] = hl[i-1]*base + (s[i]-'a'+1);
            hr[i] = hr[i-1]*base +(s[j]-'a'+1);
            p[i] = p[i-1]*base;
        }
        int res = 0;
        int l, r;
        for(int i = 1; i <= n; i++)
        {
            l = 0, r = min(i-1, n-i);
            while(l < r)
            {
                int mid = (l+r+1)>>1;
                if(query(hl, i-mid, i-1) != query(hr, n-(i+mid)+1, n-(i+1)+1))r = mid-1;
                else l = mid;
            }
            if(s[i-l] <= 'z')res = max(res, l+1);
            else res = max(res, l);
        }
        printf("Case %d: %d\n", ++ca, res);
    }

    return 0;
}


代码2:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2000100;
char Ma[maxn];
int Mp[maxn];
char s[maxn];
void Manacher(char s[], int len){
     int l = 0;
     Ma[l++] = '$';
     Ma[l++] = '#';
     for(int i = 0; i < len; i++){
        Ma[l++] = s[i];
        Ma[l++] = '#';
     }
     Ma[l] = 0;
     int mx = 0, id = 0;
     for(int i = 0; i < l; i++){
        Mp[i] = mx > i ? min(Mp[2*id-i], mx-i):1;
        while(Ma[i+Mp[i]] == Ma[i-Mp[i]])Mp[i]++;
        if(i+Mp[i] > mx){
            mx = i+Mp[i];
            id = i;
        }
     }

}
int main(){
    int ca = 0;
    while(scanf("%s",s), strcmp(s, "END")){
        int len = strlen(s);
        Manacher(s, len);
        int ans = 0;
        for(int i = 0; i < 2*len+2; i++){
            ans = max(ans, Mp[i]-1);
        }
        printf("Case %d: %d\n",++ca, ans);
    }
return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值