Skip to content

Commit

Permalink
eertree first (#173)
Browse files Browse the repository at this point in the history
* eertree first

* minor fix

* Update Codigos/String/EertreE/README.md

Co-authored-by: João Oliveira <[email protected]>

* Update Codigos/String/EertreE/README.md

Co-authored-by: João Oliveira <[email protected]>

* Update Codigos/String/EertreE/README.md

Co-authored-by: João Oliveira <[email protected]>

* Update Codigos/String/EertreE/README.md

Co-authored-by: João Oliveira <[email protected]>

---------

Co-authored-by: João Oliveira <[email protected]>
  • Loading branch information
eemoreira and joaomarcosth9 authored Sep 30, 2024
1 parent 3ba640d commit 2fe5b94
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Codigos/String/EertreE/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# [EertreE](eertree.cpp)

Constrói a Palindromic Tree de uma string $S$ em $\mathcal{O}(|S|)$. Todo nodo da árvore representa exatamente uma substring palindrômica de $S$.

- `len[u]` representa o tamanho do palíndromo representado pelo nodo `u`.
- `lnk[u]` é o nodo que representa o maior sufixo palindrômico do nodo `u`.
- `cnt[u]` é a frequência da substring representada pelo nodo `u`.
- `first[u]` representa a primeira ocorrência da substring representada pelo nodo `u`, note que `first[u]` guarda o índice do último caractere dessa substring.
- `number_of_palindromes()` retorna a quantidade de substrings palindrômicas de $S$, lembre-se de chamar a função `build_cnt()` antes dessa.
- `number_of_distinct_palindromes()` retorna a quantidade de substrings palindrômicas distintas.
54 changes: 54 additions & 0 deletions Codigos/String/EertreE/eertree.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const int N = 6e6 + 15;
const int ALF = 10;

struct eertree {
int str[N], len[N], lnk[N], cnt[N], first[N], node_cnt, it, last;
ll palindrome_substring_sum;
const char norm = '0';
array<int, ALF> to[N];

inline int get(char c) { return c - norm; }

void set_string(const string &s) {
int n = (int)s.size();
memset(str, 0, sizeof(int) * (it + 1));
memset(len, 0, sizeof(int) * (it + 1));
memset(lnk, 0, sizeof(int) * (it + 1));
memset(cnt, 0, sizeof(int) * (it + 1));
for (int i = 0; i <= it; i++)
for (int j = 0; j < ALF; j++) to[i][j] = 0;
node_cnt = 2, it = 1, last = 0, str[0] = -1;
len[0] = 0, len[1] = -1, lnk[0] = 1, lnk[1] = 1;
for (int i = 0; i < n; i++) insert(s[i]);
build_cnt();
}

void insert(char ch) {
int c = get(ch);
str[it] = c;
while (str[it - 1 - len[last]] != c) last = lnk[last];
if (!to[last][c]) {
int prev = lnk[last];
while (str[it - 1 - len[prev]] != c) prev = lnk[prev];
lnk[node_cnt] = to[prev][c];
len[node_cnt] = len[last] + 2;
to[last][c] = node_cnt++;
}
last = to[last][c];
first[last] = it;
cnt[last]++;
it++;
}

void build_cnt() {
ll ans = 0;
for (int i = it; i > 1; i--) {
ans += cnt[i];
cnt[lnk[i]] += cnt[i];
}
palindrome_substring_sum = ans;
}

inline ll number_of_palindromes() { return palindrome_substring_sum; }
inline int number_of_distinct_palindromes() { return node_cnt - 2; }
} et;

0 comments on commit 2fe5b94

Please sign in to comment.