Cod sursa(job #1797055)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 3 noiembrie 2016 23:00:51
Problema PScPld Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.81 kb
#include <iostream>

#define maxn 1000010

using namespace std;

struct node {
    int len, count, suf, to[26];
}node[maxn];

class PalTree {
 public:
    int uneven_root, even_root, current_suf, total_nodes;
    string s;
    int last;

    bool finished() {
        return last >= s.length();
    }

    void read() {
        cin >> s;
        last = 0;
    }

    PalTree() {
        uneven_root = 1;
        node[uneven_root].len = -1;
        even_root = 2;
        node[even_root].len = 0;
        node[even_root].suf = uneven_root;
        current_suf = even_root;
        total_nodes = 2;
    }

    int follow_suf(int d) {
        while(last - node[d].len - 1 < 0 || s[last] != s[last - node[d].len - 1])
            d = node[d].suf;
        return d;
    }

    int advance() {
        int match_suf = follow_suf(current_suf);
        int new_suf;
        if (node[match_suf].to[s[last]-'a'] == 0) {
            new_suf = ++total_nodes;
            node[new_suf].len = node[match_suf].len + 2;
            node[match_suf].to[s[last]-'a'] = new_suf;
            if (match_suf == uneven_root) {
                node[new_suf].suf = even_root;
            } else {
                node[new_suf].suf = node[follow_suf(node[match_suf].suf)].to[s[last]-'a'];
            }
        } else {
            new_suf = node[match_suf].to[s[last]-'a'];
        }
        current_suf = new_suf;
        node[current_suf].count = node[node[current_suf].suf].count + 1;
        ++last;
        return node[current_suf].count;
    }
};

int main() {
    freopen("pscpld.in", "r", stdin);
    freopen("pscpld.out", "w", stdout);
    PalTree pal_tree;
    pal_tree.read();
    long long ans = 0;
    while(!pal_tree.finished()) {
        ans += pal_tree.advance();
    }
    cout << ans;
}