voidexpand(string &s, int left, int right, vector<pair<int, int>> &pals){ while (left >= 0 && right < s.size() && s[left] == s[right]) { pals.emplace_back(left, right); left--; right++; } } voidsolve() { string s; cin >> s; int n = s.size(); vector<pii> pals; for (int i = 0; i < n; i++) { expand(s, i, i, pals); expand(s, i, i + 1, pals); } vi cnt_start(n, 0); for (auto& p:pals) { cnt_start[p.first]++; } vi suffix(n+1,0); for (int i = n - 1; i >= 0; --i) { suffix[i] = suffix[i+1]+cnt_start[i]; } int total = 0; for (auto & p: pals) { int end = p.second; if (end + 1 < n) { total += suffix[end + 1]; } } cout << total << endl; }
如果字符串 s 是回文串,我们称 s 为 1 阶回文串。 如果字符串 s 的左半部分等于 s 的右半部分,且左半部分和右半部分都是 k-1 阶回文串,我们称 s 为 k 阶回文串(k > 1)。 注:设 m = floor(len(s)/2),「左半部分」指 s 的长为 m 的前缀,「右半部分」指 s 的长为 m 的后缀。
voidsolve() { string s; cin >> s; int n = s.size(); vector<vector<bool>> isPal(n, vector<bool>(n, false)); vector<vector<short>> order(n, vector<short>(n, 0));
for (int len = 1; len <= n; ++len) { for (int l = 0; l + len - 1 < n; ++l) { int r = l + len - 1; if (len == 1) { isPal[l][r] = true; } elseif (len == 2) { isPal[l][r] = (s[l] == s[r]); } else { isPal[l][r] = (s[l] == s[r] && isPal[l+1][r-1]); } } }
for (int len = 1; len <= n; ++len) { for (int l = 0; l + len - 1 < n; ++l) { int r = l + len - 1; if (isPal[l][r]) { if (len == 1) { order[l][r] = 1; } else { int current_order = 1; int left_l, left_r, right_l, right_r; if (len % 2 == 0) { int mid = len / 2; left_l = l; left_r = l + mid - 1; right_l = l + mid; right_r = r; } else { int mid = len / 2; left_l = l; left_r = l + mid - 1; right_l = l + mid + 1; right_r = r; } if (isPal[left_l][left_r] && isPal[right_l][right_r] && order[left_l][left_r] == order[right_l][right_r]) { current_order = order[left_l][left_r] + 1; } order[l][r] = current_order; } } } }
vector<int> ans(n + 2, 0); for (int l = 0; l < n; ++l) { for (int r = l; r < n; ++r) { if (isPal[l][r]) { int k = order[l][r]; if (k <= n) ans[k]++; } } }
for (int i = n; i >= 1; --i) { ans[i] += ans[i + 1]; }
for (int i = 1; i <= n; ++i) { cout << ans[i] << " \n"[i == n]; } }