Cod sursa(job #915937)

Utilizator danalex97Dan H Alexandru danalex97 Data 15 martie 2013 16:29:29
Problema PScPld Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.58 kb
#include <fstream>
#include <cstring>
using namespace std;

ifstream F("pscpld.in");
ofstream G("pscpld.out");

const int Nmax = 2000010;

int N,P[Nmax];
char A[Nmax];
int Left,Right,Ref;

void Extend(int Left,int Right,int Ref)
{
    P[Ref] += int( A[Ref] != '#' );
    while ( A[Left-1] == A[Right+1] )
    {
        --Left , ++Right;
        P[Ref] += 2 * int( A[Left] != '#' );
        if ( Left == 1 || Right == N ) break;
    }
}

// lungimea palindromului maxim pe interval e Right - Poz
#define Lung (Right-Poz)
#define Pair(x) ( x - Ref > 0 ? Ref - ( x - Ref ) : Ref + ( Ref - x ) )

int main()
{
    char in[Nmax>>1]; memset(in,0,sizeof(in));
    F.getline(in,Nmax>>1,'\n'); int l = strlen(in);

    for (int i=0;i<l;++i)
        A[++N] = '#', A[++N] = in[i];
    A[++N] = '#';

    P[1] = P[2] = 0, Left = Right = Ref = 2;
    Extend(Left,Right,Ref);

    while ( Ref <= N )
    {
        int Poz = Ref, Start = Ref;
        while ( Poz < Right )
        {
            ++Poz;
            if ( Lung > P[ Pair(Poz) ] )
                P[Poz] = P[ Pair(Poz) ];
            else
            {
                int Left2 = Ref , Right2 = Right;
                Extend(Left2,Right2,Poz);
                Left = Left2, Right = Right2, Ref = Poz;
                break;
            }
        }

        if ( Start == Ref )
        {
            Poz = Right+1;
            Left = Right = Ref = Poz;
            Extend(Left,Right,Ref);
        }
    }

    int Sol = 0;
    for (int i=1;i<=N;++i)
        Sol += (P[i]+1) / 2;
    G<<Sol<<'\n';
}