Pagini recente » Cod sursa (job #3255064) | Cod sursa (job #1009550) | Mexitate | Profil mihaistamatescu | Cod sursa (job #3120856)
#include <cstdio>
#include <map>
#include <string>
#include <vector>
using namespace std;
const int max_len = 1e6;
const int max_nodes = 5e5;
const int sigma = 26;
class PalindromicTree {
class Node {
public:
int length;
int visit_cnt;
int suffix;
int next[sigma];
Node() : Node(0) {}
Node(int length) {
this->length = length;
visit_cnt = 0;
suffix = -1;
for (int i = 0; i < sigma; i++) {
next[i] = -1;
}
}
};
public:
int curr_idx, str_len, next_idx;
char str[max_len];
Node nodes[max_nodes];
PalindromicTree() {
// initialize the roots of the tree
nodes[0] = Node(-1);
nodes[1] = Node(0);
nodes[0].suffix = nodes[1].suffix = 0;
str_len = 0;
curr_idx = 0;
next_idx = 2;
}
int add_chr(char ch) {
str[str_len++] = ch;
int idx = ch - 'a';
// while we can't extend the current palindrome we move to the next
// suffix
while (str_len - 2 - nodes[curr_idx].length < 0 ||
str[str_len - 2 - nodes[curr_idx].length] != ch) {
curr_idx = nodes[curr_idx].suffix;
}
// if there's already a node there we don't do anything
if (nodes[curr_idx].next[idx] != -1) {
curr_idx = nodes[curr_idx].next[idx];
return nodes[curr_idx].visit_cnt;
}
// otherwise, we create a node that is the son of the current node
nodes[next_idx++].length = nodes[curr_idx].length + 2;
nodes[curr_idx].next[idx] = next_idx - 1;
// if the length is 1, the suffix will be the even root
if (nodes[next_idx - 1].length == 1) {
nodes[next_idx - 1].suffix = 1;
nodes[next_idx - 1].visit_cnt = 1;
curr_idx = next_idx - 1;
return nodes[next_idx - 1].visit_cnt;
}
// we now compute the suffix of the new node
curr_idx = nodes[curr_idx].suffix;
while (str_len - 2 - nodes[curr_idx].length < 0 ||
str[str_len - 2 - nodes[curr_idx].length] != ch) {
curr_idx = nodes[curr_idx].suffix;
}
nodes[next_idx - 1].suffix = nodes[curr_idx].next[idx];
nodes[next_idx - 1].visit_cnt =
1 + nodes[nodes[next_idx - 1].suffix].visit_cnt;
curr_idx = next_idx - 1;
return nodes[curr_idx].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;
}