Pagini recente » Statistici Karol Bednorz (karolb2011) | Profil tavi.belu1994 | amcbn | Diamante | Cod sursa (job #3120846)
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
const int max_len = 1e6;
const int sigma = 26;
class PalindromicTree {
class Node {
public:
int length;
int visit_cnt;
Node *suffix;
Node *next[sigma];
Node(int length) {
this->length = length;
visit_cnt = 0;
suffix = NULL;
for (int i = 0; i < sigma; i++) {
next[i] = NULL;
}
}
~Node() {
for (int i = 0; i < sigma; i++) {
if (next[i] != NULL) {
delete next[i];
next[i] = NULL;
}
}
}
};
public:
string str;
Node *odd_root;
Node *even_root;
Node *curr_node;
PalindromicTree() {
// initialize the roots of the tree
odd_root = new Node(-1);
even_root = new Node(0);
odd_root->suffix = odd_root;
even_root->suffix = odd_root;
curr_node = odd_root;
}
~PalindromicTree() {
delete odd_root;
delete even_root;
even_root = odd_root = NULL;
}
int add_chr(char ch) {
str.push_back(ch);
int idx = ch - 'a';
// while we can't extend the current palindrome we move to the next
// suffix
while ((int)str.size() - 2 - curr_node->length < 0 ||
str[str.size() - 2 - curr_node->length] != ch) {
curr_node = curr_node->suffix;
}
// if there's already a node there we don't do anything
if (curr_node->next[idx] != NULL) {
curr_node = curr_node->next[idx];
return curr_node->visit_cnt;
}
// otherwise, we create a node that is the son of the current node
Node *new_node = new Node(curr_node->length + 2);
curr_node->next[idx] = new_node;
// if the length is 1, the suffix will be the even root
if (new_node->length == 1) {
new_node->suffix = even_root;
new_node->visit_cnt = 1;
curr_node = new_node;
return new_node->visit_cnt;
}
// we now compute the suffix of the new node
curr_node = curr_node->suffix;
while ((int)str.size() - 2 - curr_node->length < 0 ||
str[str.size() - 2 - curr_node->length] != ch) {
curr_node = curr_node->suffix;
}
new_node->suffix = curr_node->next[idx];
new_node->visit_cnt = 1 + new_node->suffix->visit_cnt;
curr_node = new_node;
return curr_node->visit_cnt;
}
};
int main() {
freopen("pscpld.in", "r", stdin);
freopen("pscpld.out", "w", stdout);
long long ans = 0;
PalindromicTree T;
char str[max_len + 1];
scanf("%s", str);
for (int i = 0; str[i] != '\0'; i++) {
ans += T.add_chr(str[i]);
}
printf("%lld\n", ans);
return 0;
}