Pagini recente » Cod sursa (job #2055773) | Cod sursa (job #1346613) | Cod sursa (job #1778222) | Cod sursa (job #2059035) | Cod sursa (job #1138383)
#include <iostream>
#include <fstream>
#include <cstring>
#include <cassert>
using namespace std;
const int NMax = 1000010;
char a[NMax * 2], v[NMax];
int n;
long long ans;
int dp[NMax];
/// dp[i] = jumatate din lungimea maxima a unui palindrom de lungime impara cu centrul in i
int main()
{
ifstream f("pscpld.in");
f>>(v+1);
f.close();
n = strlen(v+1);
int sz = 0;
for(int i = 1; i<=n; ++i)
a[++sz] = '$', a[++sz] = v[i];
a[sz + 1] = '$';
++sz;
n = sz;
//cout<<(a+1);
int maxim = 1; /// valoarea cea mai mare pentru j + dp[j] adica cel mai din dreapta capat al unui palindrom centrat in j cu j < i
int position = 1; /// position = acel j pentru care j + dp[j] e maxim
dp[1] = 0;
for (int i = 2; i <= n; ++i)
{
if (maxim < i)
{
int st, dr;
for (st = dr = i; st - 1 >= 1 && dr + 1 <= n && a[st - 1] == a[dr + 1]; --st, ++dr);
dp[i] = (dr - st) / 2;
maxim = i + dp[i];
position = i;
}
else
{
int iprim = position - (i - position); /// iprim = simetricul lui i fata de position
if (dp[iprim] + i < maxim)
dp[i] = dp[iprim];
else
{
/// luam pana la maxim si apoi cautam brut restul palindromului (daca exista)
/// si actualizam maximul.
dp[i] = min(dp[iprim], maxim - i);
int st, dr;
for (dr = maxim, st = i - (maxim - i); st - 1 >= 1 && dr + 1 <= n && a[st - 1] == a[dr + 1]; --st, ++dr, ++dp[i]);
if (i + dp[i] > maxim)
maxim = i + dp[i], position = i;
}
}
}
for (int i = 1; i <= n; ++i)
ans += 1LL * (dp[i] + 1) / 2;
ofstream g("pscpld.out");
g<<ans<<"\n";
g.close();
return 0;
}