p4555 最长双回文串 最后两个样例过不了求教
  • 板块学术版
  • 楼主Emmmhihihi
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/28 13:15
  • 上次更新2024/3/28 13:36:20
查看原帖
p4555 最长双回文串 最后两个样例过不了求教
803199
Emmmhihihi楼主2024/3/28 13:15

最后ans遍历去掉第一个最后一个#就能过,不去掉就过不了,疑惑好久,球球大佬教教。

#include <iostream>
#include<algorithm>
#include<string>
using namespace std;
const int maxn = 1e5 + 10;
int p[2*maxn];
int l[2*maxn];//#左侧的回文串长度==回文中心到#的半径
int r[2*maxn];//#右侧的回文串长度
string s;
int k = 1;
string get_new(string& s) {
    string tmp = "$#";
    for (int i = 0; i < s.size(); i++) (tmp += s[i]) += "#";
    return tmp;
}
int main(){
    cin >> s;
    s = get_new(s);
    for (int i = 1; s[i]; i++) {
        if (k + p[k] > i) p[i] = min(p[k * 2 - i], k + p[k] - i);
        while (s[i - p[i]] == s[i + p[i]]) p[i]++;
        --p[i];
        if (i + p[i] > k + p[k]) k = i;
        l[i + p[i]] = max(l[i + p[i]], p[i]);
        r[i - p[i]] = max(r[i - p[i]], p[i]);
    }

    for (int i = 3; i < s.size(); i += 2) r[i] = max(r[i], r[i - 2] - 2);//从左到右更新右侧长度
    for (int i = s.size()-3; i > 0; i -= 2) l[i] = max(l[i], l[i + 2] - 2);//从右到左更新左侧长度
    int ans = 0;//统计#左右侧长度和的最大值
    for (int i = 1; i < s.size(); i += 2) {//为何去掉首尾#
        ans = max(ans, l[i] + r[i]);
    }
    cout << ans;
}

2024/3/28 13:15
加载中...