Acwing-139 迴文子串的最大長度(Hash+二分)

Acwing-139. 迴文子串的最大長度

如果一個字符串正着讀和倒着讀是一樣的,則稱它是迴文的。

給定一個長度爲N的字符串S,求他的最長迴文子串的長度是多少。

輸入格式

輸入將包含最多30個測試用例,每個測試用例佔一行,以最多1000000個小寫字符的形式給出。

輸入以一個以字符串“END”(不包括引號)開頭的行表示輸入終止。

輸出格式

對於輸入中的每個測試用例,輸出測試用例編號和最大回文子串的長度(參考樣例格式)。

每個輸出佔一行。

輸入樣例:

abcbabcbabcba
abacacbaaaab
END

輸出樣例:

Case 1: 13
Case 2: 6

鏈接:https://www.acwing.com/problem/content/141/

思路:(Hash字符串+二分)

迴文串:正着反着讀一樣的 例如:abcba

當迴文串的長度爲偶數時,那麼我們可以給每個元素前加一個字符#。例如abba->#a#b#b#a,那麼迴文串長度就變爲了奇數。

當迴文串的長度爲奇數時,那麼我們可以給每個元素前加一個字符#。例如aba->#a#b#a,那麼迴文串長度也是奇數。

這樣我們就把兩種情況處理爲一種情況,利於操作(當然也可以分開討論)。

我們可以以每一位爲中點,二分長度,來找最大回文串,當此時長度滿足迴文串那麼我們擴大長度。當此時長度不滿足迴文串,我們就縮小長度。

怎麼判斷是不是迴文串:

我們可以正着Hash和反着Hash,當正着Hash值等於反着Hash值時,此時就相等(下標不要弄錯)。

代碼:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2000000+20;
const int base = 131;
typedef unsigned long long ULL;
ULL f[maxn], f2[maxn], t[maxn];

char s[maxn];
ULL solve(ULL h[],int l, int r)
{
    return h[r] - h[l-1] * t[r-l+1];
}
int main()
{
    int T = 1;
    while(scanf("%s", s+1) != EOF) {
        int len = strlen(s+1);
        if(!strcmp(s+1, "END"))
            break;
        for(int i = 2*len; i > 0; i-=2) {
            s[i] = s[i/2];
            s[i-1] = 'z'+1;
        }
        len *= 2;
        f[0] = f2[0] = 0;
        t[0] = 1;
        for(int i = 1, j = len; i <= len; i++, j--) {
            f[i] = f[i-1]*base + (s[i] - 'a' + 1);
            f2[i] = f2[i-1]*base + (s[j] - 'a' + 1);
            t[i] = t[i-1] * base;
        }
        int l, r;
        int ans = 0;
        int mid;
        for(int i = 1; i <= len; i++) {
            l = 0, r = min(i-1, len-i);
            while(l < r) {
                mid = (l+r+1)>>1;
                if(solve(f,i-mid,i-1) != solve(f2,len-(i+mid)+1,len-(i+1)+1))
                    r = mid-1;
                else
                    l = mid;
            }
            if(s[i-l] <= 'z')
                ans = max(ans, l+1);
            else
                ans = max(ans, l);

        }
        printf("Case %d: %d\n", T++, ans);

    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章