Cod sursa(job #1427090)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 1 mai 2015 15:12:22
Problema PScPld Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_LEN = 500000;
const int SIGMA = 26;

struct PalindromicTree
{
    struct Node
    {
        int next[SIGMA];
        int length;
        int suffixLink;
        int countPalindromes;
    };

    Node Tree[MAX_LEN + 2 + 1];
    char String[MAX_LEN + 1];

    int countNodes;
    int lastNode;
    int lengthString;

    PalindromicTree() : countNodes(2), lastNode(2), lengthString(0)
    {
        Tree[1].length = -1; Tree[1].suffixLink = 1;
        Tree[2].length =  0; Tree[2].suffixLink = 1;
    }

    bool addLetter(int c)
    {
        String[ lengthString++ ] = c;

        int node = lastNode;
        int lg = 0;

        while (true)
        {
            lg = Tree[node].length;

            if (lengthString - 2 - lg >= 0 && String[lengthString - 2 - lg] == String[lengthString - 1])
                break;

            node = Tree[node].suffixLink;
        }

        if (Tree[node].next[c] != 0)
        {
            lastNode = Tree[node].next[c];

            return false;
        }

        lastNode = ++countNodes;
        Tree[lastNode].length = Tree[node].length + 2;
        Tree[node].next[c] = lastNode;

        if (Tree[lastNode].length == 1)
        {
            Tree[lastNode].suffixLink = 2;
            Tree[lastNode].countPalindromes = 1;

            return true;
        }

        node = Tree[node].suffixLink;

        while (true)
        {
            lg = Tree[node].length;

            if (lengthString - 2 - lg >= 0 && String[lengthString - 2 - lg] == String[lengthString - 1])
                break;

            node = Tree[node].suffixLink;
        }

        Tree[lastNode].suffixLink = Tree[node].next[c];
        Tree[lastNode].countPalindromes = Tree[ Tree[lastNode].suffixLink ].countPalindromes + 1;

        return true;
    }

    int countPalindromes() const
    {
        return Tree[lastNode].countPalindromes;
    }
};

char str[MAX_LEN];
PalindromicTree P;

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

    scanf("%s", str);
    int n = strlen(str);
    long long sol = 0;

    for (int i = 0; i < n; ++i)
    {
        P.addLetter(str[i] - 'a');
        sol += P.countPalindromes();
    }

    cout << sol << "\n";

    return 0;
}