Cod sursa(job #1736312)

Utilizator AlexNiuclaeNiculae Alexandru Vlad AlexNiuclae Data 1 august 2016 15:55:17
Problema PScPld Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.93 kb
#include <bits/stdc++.h>
using namespace std;

const int nmax = 1e6 + 10;

int n;
int max_expand[nmax<<1], bst[nmax<<1], let[nmax<<1];
char s[nmax], sir[nmax<<1];

int letters(int a , int b)
{
    return let[b] - let[a-1];
}

long long manacher(char aux[nmax])
{
    long long sol = 0;
    int i , lg(0), right(0), C(0);

    sir[lg] = '$'; sir[++lg] = '#';
    for (i = 1; i <= n; ++i)
    {
        sir[++lg] = aux[i];
        sir[++lg] = '#';
    }
    sir[lg+1] = '*';

    for (i = 1; i <= lg; ++i)
         let[i] = (isalpha(sir[i])) ? let[i-1] + 1 : let[i-1],
         bst[i] = 1;

    for (i = 1; i <= lg; ++i)
    {
        int simetric_C = C - (i - C);
        max_expand[i] = (right > i) ? min(max_expand[simetric_C] , right - i) : 0;

        while (sir[i+max_expand[i]+1] == sir[i-max_expand[i]-1])
            max_expand[i]++,
            bst[i+max_expand[i]] = letters(i - max_expand[i], i + max_expand[i]);

        sol += 1LL * (max_expand[i] + 1) >> 1;

        if (i + max_expand[i] > right)
            C = i, right = i + max_expand[i];
    }

    return sol;
}

struct Tree
{
    int number , link , length;
    int letter[26];
};

long long ans;

int nrNodes , actNode;

Tree tree[nmax];

int v[nmax] , nr;

void initTree()
{
    nrNodes = 2; actNode = 2;
    tree[1].length = -1; tree[1].link = 1;
    tree[2].length = 0; tree[2].link = 1;
}

int newPalindromes(int pos)
{
    int act = actNode;

    for (act = actNode; ; act = tree[act].link)
    {
        int actL = tree[act].length;
        if (pos - actL - 1 > 0 && s[pos-actL-1] == s[pos])
            break;
    }

    if (tree[act].letter[s[pos]-'a'])
    {
        actNode = tree[act].letter[s[pos]-'a'];
        return tree[actNode].number;
    }

    nrNodes++; actNode = nrNodes;
    tree[act].letter[s[pos]-'a'] = nrNodes;
    tree[nrNodes].length = tree[act].length + 2;

    if (act == 1)
    {
        tree[nrNodes].link = 2;
        return tree[nrNodes].number = 1;
    }

    for (act = tree[act].link ; ; act = tree[act].link)
    {
        int actL = tree[act].length;
        if (pos - actL - 1 > 0 && s[pos-actL-1] == s[pos])
            break;
    }

    act = tree[act].letter[s[pos]-'a'];

    tree[nrNodes].link = act;
    return tree[nrNodes].number = 1 + tree[act].number;
}

int main()
{
    freopen("pscpld.in","r",stdin);
    freopen("pscpld.out","w",stdout);

    gets(s + 1); n = strlen(s + 1);
    reverse(s + 1 , s + n + 1);

    manacher(s);
    for (int i = 2 * n; i >= 2 ; i -= 2)
        v[++nr] = bst[i];

    reverse(s + 1 , s + n + 1);

    initTree();
    for (int i = 1; i <= n; ++i)
    {
        ans += newPalindromes(i);
        //printf("%d\n", tree[actNode].length);
        if (tree[actNode].length != v[n-i+1])
        {
            printf("PULaaaaaaa\n");
            return 0;
        }
    }

    printf("%lld\n", ans);

    return 0;
}