专栏文章

题解:AT1202Contest_e Half Palindromes

AT1202Contest_e题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio6jt6x
此快照首次捕获于
2025/12/02 14:11
3 个月前
此快照最后确认于
2025/12/02 14:11
3 个月前
查看原文
#include #include #include #include using namespace std;
// Manacher算法计算最长回文子串半径(奇数长度) vector manacher_odd(const string &s) { int n = s.size(); vector p(n); int l = 0, r = -1; for (int i = 0; i < n; ++i) { int k = (i > r) ? 1 : min(p[l + r - i], r - i + 1); while (0 <= i - k && i + k < n && s[i - k] == s[i + k]) { k++; } p[i] = k--; if (i + k > r) { l = i - k; r = i + k; } } return p; }
int main() { string S; cin >> S; int n = S.size(); if (n == 0) { cout << 0 << endl; return 0; }
CPP
// 计算每个位置的最长奇数长度回文半径
vector<int> p = manacher_odd(S);

long long t = 0;

// 枚举所有子串S[i..j]
for (int i = 0; i < n; ++i) {
    // 对于每个i,找到最大的回文半径中心
    int max_r = 0;
    for (int c = i; c < n; ++c) {
        // 计算以c为中心,覆盖i的最大半径
        int possible_r = min(p[c], c - i + 1);
        max_r = max(max_r, possible_r);
        
        int len = c - i + 1;
        // 计算当前子串的最小长度
        int min_len = len - (max_r - 1);
        t+= min_len;
    }
}

cout << t << endl;
return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...