Cod sursa(job #1797125)

Utilizator Impaler_009Mihai Nitu Impaler_009 Data 3 noiembrie 2016 23:44:34
Problema PScPld Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.78 kb
#include <iostream>
#include <map>
#include <cstdio>

#define maxn 1000001

using namespace std;

struct node {
    int len, count;
    int suf;
    map<int, int> to;
};

class PalTree {
 public:
    int uneven_root, even_root, current_suf, total_nodes;
    node t[maxn];
    string s;
    int last;

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

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

    PalTree() {
        uneven_root = ++total_nodes;
        t[uneven_root].len = -1;
        t[uneven_root].count = 0;
        even_root = ++total_nodes;
        t[even_root].len = 0;
        t[even_root].count = 0;
        t[even_root].suf = uneven_root;
        current_suf = even_root;
    }

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

    int advance() {
        int c = s[last]-'a';
        int match_suf = follow_suf(current_suf);
        auto it = t[match_suf].to.find(c);
        if (it == t[match_suf].to.end()) {
            int suf_link = match_suf == uneven_root ? even_root : t[follow_suf(t[match_suf].suf)].to[c];
            t[match_suf].to[c] = current_suf = ++total_nodes;
            t[current_suf].len = t[match_suf].len + 2;
            t[current_suf].suf = suf_link;
            t[current_suf].count = t[suf_link].count + 1;
        } else {
            current_suf = it->second;
        }
        ++last;
        return t[current_suf].count;
    }
}pal_tree;

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