Cod sursa(job #888981)

Utilizator mlupseLupse-Turpan Mircea mlupse Data 24 februarie 2013 12:28:57
Problema PScPld Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.61 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

#define NMax 1000005

using namespace std;

int N, DP[2][NMax];
char X[NMax];
long long S;

int Expand (int Left, int Right)
{
    int Length=0;
    while (Left>0 and Right<=N and X[Left]==X[Right])
    {
        --Left, ++Right, ++Length;
    }
    return Length;
}

void SolveUneven ()
{
    int P=0, R=0;
    for (int i=1; i<=N; ++i)
    {
        int Left, Right;
        if (R>=i)
        {
            DP[0][i]=min (DP[0][P-(i-P)], R-i);
        }
        Left=i-DP[0][i];
        Right=i+DP[0][i];
        DP[0][i]+=Expand (Left, Right);
        if (i+DP[0][i]>R)
        {
            P=i;
            R=i+DP[0][i];
        }
        S+=((long long)DP[0][i]);
    }
}

void SolveEven ()
{
    int P=0, R=0;
    for (int i=1; i<=N; ++i)
    {
        int Left, Right;
        if (X[i]!=X[i+1])
        {
            continue;
        }
        if (R>i)
        {
            DP[1][i]=min (DP[1][P-(i-P)], R-i-1);
        }
        Left=i-DP[1][i];
        Right=i+1+DP[1][i];
        DP[1][i]+=Expand (Left, Right);
        if (i+1+DP[1][i]>R)
        {
            P=i;
            R=i+1+DP[1][i];
        }
        S+=((long long)DP[1][i]);
    }
}

void Read ()
{
    freopen ("pscpld.in", "r", stdin);
    scanf ("%s", X);
    N=strlen (X);
    for (int i=N; i>0; --i)
    {
        X[i]=X[i-1];
    }
}

void Print ()
{
    freopen ("pscpld.out", "w", stdout);
    printf ("%lld\n", S);
}

int main()
{
    Read ();
    SolveUneven ();
    SolveEven ();
    Print ();
    return 0;
}