Pagini recente » Cod sursa (job #3332684) | Cod sursa (job #3320278) | Cod sursa (job #3317714) | Cod sursa (job #3322525) | Cod sursa (job #3327454)
#include <bits/stdc++.h>
using namespace std;
// Functia data de tine, aplicata pe sirul transformat (cu # intre caractere)
// Intoarce, pentru fiecare pozitie, raza palindromului impar centrat acolo.
vector<int> manacher_odd(string s) {
int n = s.size();
s = "$" + s + "^";
vector<int> p(n + 2);
int l = 0, r = 1;
for (int i = 1; i <= n; i++) {
p[i] = min(r - i, p[l + (r - i)]);
while (s[i - p[i]] == s[i + p[i]]) {
p[i]++;
}
if (i + p[i] > r) {
l = i - p[i];
r = i + p[i];
}
}
return vector<int>(begin(p) + 1, end(p) - 1);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
freopen("pscpld.in", "r", stdin);
freopen("pscpld.out", "w", stdout);
string s;
if (!(cin >> s)) {
return 0;
}
// Construim sirul transformat: #a#b#a#...
string t;
t.reserve(2 * s.size() + 1);
for (char c : s) {
t.push_back('#');
t.push_back(c);
}
t.push_back('#');
// Aplicam Manacher pe sirul transformat
vector<int> p = manacher_odd(t);
// Numarul de subsecvente palindrom in sirul original este
// suma floor(p[i] / 2), pentru toate i
long long ans = 0;
for (int x : p) {
ans += x / 2;
}
cout << ans;
return 0;
}