Cod sursa(job #468355)

Utilizator eudanipEugenie Daniel Posdarascu eudanip Data 3 iulie 2010 11:15:21
Problema PScPld Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.06 kb
#include<stdio.h>
#include<string.h>

#define minim(a,b) (a<b ? a : b)
#define ll long long

int n,nr,l,r,d[2000007];
char s[1000006],dif[2000006];
ll sol;


int main ()
{
    int i,st,dr,c;
    freopen("pscpld.in","r",stdin);
    freopen("pscpld.out","w",stdout);
    gets(s);
    nr=strlen(s);
    n=nr+1;
    for(i=n;i>=1;i--)
        dif[i]=s[i-1];
    l=r=1;d[1]=1;
    for(i=2;i<n;i++)
        if(i>r)
        {
            d[i]=1;st=i-1;dr=i+1;
            while(dif[st]==dif[dr] && st && dr<n)
            {
                d[i]++;
                st--;
                dr++;
            }
            l=st+1;r=dr-1;
        }
        else
        {
            c=(l+r)/2;
            if(d[2*c-i]<=r-i)
            {
                d[i]=minim(d[2*c-i],n-i);
                continue;
            }
            d[i]=r-i+1;
            st=i-d[i];dr=i+d[i];
            while(dif[st]==dif[dr] && st && dr<n)
            {
                d[i]++;
                st--;
                dr++;
            }
            l=st+1;r=dr-1;
        }
    for(i=1;i<n;i++)
        sol+=d[i];
    memset(d,0,sizeof(d));
    n=0;
    for(i=0;i<nr;i++)
    {
        dif[++n]=s[i];
        dif[++n]='!';
    }
    l=r=1;d[1]=1;
    for(i=2;i<n;i++)
        if(i>r)
        {
            d[i]=1;st=i-1;dr=i+1;
            while(dif[st]==dif[dr] && st && dr<n)
            {
                d[i]++;
                st--;
                dr++;
            }
            l=st+1;r=dr-1;
        }
        else
        {
            c=(l+r)/2;
            if(d[2*c-i]<=r-i)
            {
                d[i]=minim(d[2*c-i],n-i);
                continue;
            }
            d[i]=r-i+1;
            st=i-d[i];dr=i+d[i];
            while(dif[st]==dif[dr] && st && dr<n)
            {
                d[i]++;
                st--;
                dr++;
            }
            l=st+1;r=dr-1;
        }
    for(i=1;i<n;i++)
        if(!(i%2))
            sol+=d[i]/2;
    printf("%lld\n",sol);
    return 0;
}