Pagini recente » Profil GeorgianBadita | Cod sursa (job #3197113) | Cod sursa (job #2608520) | Rating Andrei Gasparovici (andreigasparovici) | Cod sursa (job #1797124)
#include <iostream>
#include <map>
#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;
}
};
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;
}