Nu aveti permisiuni pentru a descarca fisierul grader_test3.ok
Cod sursa(job #3120848)
Utilizator | Data | 8 aprilie 2023 22:58:25 | |
---|---|---|---|
Problema | PScPld | Scor | 60 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva de probleme | Marime | 2.81 kb |
#include <cstdio>
#include <map>
#include <string>
using namespace std;
const int max_len = 1e6;
class PalindromicTree {
class Node {
public:
int length;
int visit_cnt;
Node *suffix;
map<int, Node *> next;
Node(int length) {
this->length = length;
visit_cnt = 0;
suffix = NULL;
}
// ~Node() {
// for (auto entry : next) {
// delete entry.second;
// }
// next.clear();
// }
};
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.find(idx) != curr_node->next.end()) {
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;
}