-
Notifications
You must be signed in to change notification settings - Fork 438
/
Palindromic-Tree.cpp
85 lines (75 loc) · 1.42 KB
/
Palindromic-Tree.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Problem Name: Palindromes
// Source: [APIO2014]
#include <cstdio>
#include <cstring>
#define NIL 0
#define ALPHABET_SIZE 26
#define STRING_LENGTH 100000
using namespace std;
struct node
{
node *next[ALPHABET_SIZE], *fail;
int start, len;
node (int _start = 0, int _len = 0) : fail(NIL), start(_start), len(_len) { memset(next, 0, sizeof(next)); }
}*root, *empty, *last;
char str[STRING_LENGTH];
int len;
void extend(char x, int pos)
{
node *u = last;
while (str[pos] != str[pos - u->len - 1]) u = u->fail;
if (u->next[x] == NIL)
{
node *cur = new node(pos - u->len - 1, u->len + 2);
u->next[x] = cur;
u = u->fail;
if (u == NIL) cur->fail = empty;
else
{
while (str[pos] != str[pos - u->len - 1]) u = u->fail;
cur->fail = u->next[x];
}
last = cur;
}
else last = u->next[x];
}
void build()
{
str[0] = '\xFF';
root = new node(0, -1);
empty = new node(0, 0);
empty->fail = root;
last = empty;
for (int i = 1; i <= len; i++)
{
extend(str[i] - 'a', i);
}
}
void print_substring(int l, int r)
{
printf("\t");
for (int i = l; i <= r; i++)
{
printf("%c", str[i]);
}
printf("\n");
}
void dfs(node *u)
{
if (u->len > 0) print_substring(u->start, u->start + u->len - 1);
for (int i = 0; i < ALPHABET_SIZE; i++)
{
if (u->next[i] != NIL) dfs(u->next[i]);
}
}
int main()
{
scanf("%s", str + 1);
len = strlen(str + 1);
build();
printf("odd:\n");
dfs(root);
printf("even:\n");
dfs(empty);
return 0;
}