Nu aveti permisiuni pentru a descarca fisierul grader_test6.ok

Cod sursa(job #3120860)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 8 aprilie 2023 23:24:37
Problema PScPld Scor 60
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.75 kb
#include <cstdio>
#include <map>
#include <string>
#include <vector>

using namespace std;

const int max_len = 1e6;
const int max_nodes = 520000;
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;
}