Pagini recente » Cod sursa (job #3364379) | Cod sursa (job #3362477) | Cod sursa (job #3363424) | Cod sursa (job #3362482) | Cod sursa (job #3364391)
/// problema PScPld infoarena
/// implementare Manacher
/// resurse explicative:
/// https://www.youtube.com/watch?v=kbUiR5YWUpQ
/// https://www.geeksforgeeks.org/dsa/manachers-algorithm-linear-time-longest-palindromic-substring-part-1/
#include <bits/stdc++.h>
using namespace std;
string is, s;
int p[1000010], N; /// p[i] = raza palindromului cu centrul in i
void prepareString()
{
s.push_back('@');
s.push_back('#');
for(size_t i = 0; i < is.size(); i++)
{
s.push_back(is[i]);
s.push_back('#');
}
s.push_back('$');
}
void manacher()
{
N = s.size();
int L = 0, R = 0;
for(int i = 1; i < N - 1; i++)
{
int mirror = R + L - i;
/// initializez p[i]
if(i < R)
{
p[i] = min(R - i, p[mirror]);
}
/// extind palindromul si maresc raza cat se poate
while(i + p[i] + 1 < N && i - p[i] - 1 >= 0 && s[i + p[i] + 1] == s[i - p[i] - 1])
{
p[i]++;
}
/// modific capetele L si R, daca e nevoie
if(i + p[i] > R)
{
L = i - p[i];
R = i + p[i];
}
}
}
long long getAnswer()
{
long long sum = 0;
for(int i = 2; i < N - 2; i++)
{
sum += p[i] / 2 + (1 - i % 2);
}
return sum;
}
int main()
{
ifstream cin("pscpld.in");
ofstream cout("pscpld.out");
cin>>is;
prepareString();
manacher();
cout<< getAnswer();
return 0;
}