Cod sursa(job #1797112)

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

using namespace std;

struct node {
    int len, count;
    node *suf;
    map<int, node*> to;
    node(int len, node* suf, int count) : len(len), suf(suf), count(count) {
    }
};

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

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

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

    PalTree() {
        uneven_root = new node(-1, NULL, 0);
        even_root = new node(0, uneven_root, 0);
        current_suf = even_root;
    }

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

    int advance() {
        int c = s[last]-'a';
        node* match_suf = follow_suf(current_suf);
        auto it = match_suf->to.find(c);
        if (it == match_suf->to.end()) {
            node *suf_link = match_suf == uneven_root ? even_root : follow_suf(match_suf->suf)->to[c];
            match_suf->to[c] = current_suf = new node(match_suf->len + 2, suf_link, suf_link->count + 1);
        } else {
            current_suf = it->second;
        }
        ++last;
        return 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;
}