Palindromic Partitions

Palindromic Partitions

找一个字符串最多能切成多少块,块与块之间形成回文。这个用greedy就可以解,从两头找最短的相同的子串,找到之后重新开始这个过程, 这样到最后子串的数量就是最多的。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
 
int T, n;
const int MAXN = 1000005;
char s[MAXN];
int h[MAXN], p[MAXN];
const int A = 96420, M = 1e9+7;
 
int main() {
    scanf("%d", &T);
    for (int t = 0; t < T; t++) {
        scanf("%s", s);
        n = strlen(s);
 
        p[0] = 1; h[0] = s[0];
        for (int i = 1; i < n; i++) {
            p[i] = ((ll)p[i-1] * A) % M;
            h[i] = ((ll)h[i-1] * A + s[i]) % M;
        }
        auto hsh = [](int a, int b) -> int {
            if (a == 0) return h[b];
            else return (h[b] - (ll)h[a-1] * p[b-a+1] + (ll)h[a-1] * M) % M;
        };
 
        int j = 0;
        int cnt = 0;
        for (int i = 0; i < n/2; i++) {
            if (hsh(j,i) == hsh(n-i-1,n-j-1)) {
                cnt+=2;
                j = i+1;
            }
        }
        if (j < n/2) cnt++;
        else if (j == n/2 && n%2 == 1) cnt++;       // 奇数长度剩下中间一个字符,需要处理下
 
        printf("%d\n", cnt);
    }
 
    return 0;
}