[Ybtoj High-efficiency Advanced 2.2] [hash] Palindrome substring

[Ybtoj High-efficiency Advanced 2.2] [hash] Palindrome substring

topic

Insert picture description here


Problem-solving ideas

Do positive and negative twice hash
enumeration center dichotomy maximum palindrome substring


Code

在这里插入代码#include <iostream>
#include <cstring>
#include <cstdio>
#define ull unsigned long long
using namespace std;
char s[10400010];
ull n, ans, len, l, r, mid;
ull power[1000010], zhash[1000010], fhash[1000010];
int main() {
    
    
    scanf("%s", s + 1);
    while (s[1] != 'E') {
    
    
        memset(zhash, 0, sizeof(zhash));
        memset(fhash, 0, sizeof(fhash));
        memset(power, 0, sizeof(power));
        n++;
        ans = 0;
        len = strlen(s + 1);
        power[0] = 1ull;
        for (int i = 1; i <= len; i++) {
    
    
            power[i] = power[i - 1] * 131ull;
            zhash[i] = zhash[i - 1] * 131ull + s[i] - 'a'; //正序hash
        }
        for (int i = len; i > 0; i--) fhash[i] = fhash[i + 1] * 131ull + s[i] - 'a'; //倒序hash
        for (int i = 1; i <= len; i++) {
    
    
            l = 0, r = len;
            while (l <= r) {
    
      //奇数
                mid = (l + r) / 2;
                if (i - mid < 1 || i + mid > len) {
    
    
                    r = mid - 1;
                    continue;
                }
                if (zhash[i] - zhash[i - mid - 1] * power[mid + 1] ==
                    fhash[i] - fhash[i + mid + 1] * power[mid + 1]) {
    
    
                    l = mid + 1;
                    ans = max(ans, mid * 2 + 1);
                } else
                    r = mid - 1;
            }
            l = 0, r = len;
            while (l <= r) {
    
      //偶数
                mid = (l + r) / 2;
                if (i - mid < 0 || i + mid > len) {
    
    
                    r = mid - 1;
                    continue;
                }
                if (zhash[i] - zhash[i - mid] * power[mid] ==
                    fhash[i + 1] - fhash[i + mid + 1] * power[mid]) {
    
    
                    l = mid + 1;
                    ans = max(ans, mid * 2);
                } else
                    r = mid - 1;
            }
        }
        printf("Case %lld: %lld\n", n, ans);
        scanf("%s", s + 1);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_45621109/article/details/114435377