#include <bits/stdc++.h>
#define Loop(x,l,r) for (ll x = (l); x < (ll)(r); ++x)
#define LoopR(x,l,r) for (ll x = (r)-1; x >= (ll)(l); --x)
typedef long long ll;
typedef std::pair<int, int> pii;
typedef std::pair<ll , ll > pll;
using namespace std;
const int N = 300'010;
const int alpha = 26;
int longest_palin[N];
int second_longest[N];
string s;
int n;
struct node {
int link = 0;
int next[alpha] = {};
int len = 0;
int cnt = 0;
bool vis = 0;
} pool[10000000];
int rt = 1;
int make_node()
{
static int nxt = 2;
return nxt++;
}
int lst_node = rt;
vector<int> all_nodes = {rt};
void insert_node(char c)
{
c -= 'a';
int new_node = make_node();
all_nodes.push_back(new_node);
pool[new_node].cnt = 1;
pool[new_node].len = pool[lst_node].len + 1;
int cur = lst_node;
lst_node = new_node;
while (cur) {
if (!pool[cur].next[c]) {
pool[cur].next[c] = new_node;
cur = pool[cur].link;
} else {
break;
}
}
if (!cur) {
pool[new_node].link = rt;
return;
}
int q = pool[cur].next[c];
if (pool[cur].len + 1 == pool[q].len) {
pool[new_node].link = q;
return;
}
int clone = make_node();
all_nodes.push_back(clone);
pool[clone] = pool[q];
pool[clone].cnt = 0;
pool[clone].len = pool[cur].len + 1;
pool[q].link = clone;
while (cur && pool[cur].next[c] == q) {
pool[cur].next[c] = clone;
cur = pool[cur].link;
}
pool[new_node].link = clone;
}
int index2node[N];
void make_automata()
{
Loop (i,0,n) {
insert_node(s[i]);
index2node[i] = lst_node;
}
sort(all_nodes.begin(), all_nodes.end(), [](int a, int b) {
return pool[a].len < pool[b].len;
});
LoopR (i,1,all_nodes.size()) {
int t = all_nodes[i];
pool[pool[t].link].cnt += pool[t].cnt;
}
}
void find_palin(int i)
{
int j = i-1;
while (longest_palin[j] == i || s[i-longest_palin[j]-1] != s[i]) {
if (!second_longest[j]) {
longest_palin[i] = 1 + (s[i] == s[i-1]);
second_longest[i] = s[i] == s[i-1];
return;
}
int k = second_longest[j];
while(longest_palin[j] != k)
j = j-longest_palin[j]+second_longest[j];
}
longest_palin[i] = longest_palin[j]+2;
do {
if (!second_longest[j]) {
second_longest[i] = 1 + (s[i] == s[i-1]);
return;
}
int k = second_longest[j];
while(longest_palin[j] != k)
j = j-longest_palin[j]+second_longest[j];
} while (longest_palin[j] == i || s[i-longest_palin[j]-1] != s[i]);
second_longest[i] = longest_palin[j]+2;
}
void find_all_palins()
{
longest_palin[0] = 1;
second_longest[0] = 0;
Loop (i,1,n) {
find_palin(i);
}
}
int main()
{
cin.tie(0) -> sync_with_stdio(false);
cin >> s;
n = s.size();
make_automata();
find_all_palins();
ll ans = 0;
Loop (i,0,n) {
int t = index2node[i];
while (pool[pool[t].link].len >= longest_palin[i]) {
pool[t].vis = 1;
t = pool[t].link;
if (pool[t].vis)
break;
}
if (pool[t].vis)
continue;
ans = max(ans, (ll)longest_palin[i] * pool[t].cnt);
}
cout << ans << '\n';
}
Compilation message
palindrome.cpp: In function 'void insert_node(char)':
palindrome.cpp:44:23: warning: array subscript has type 'char' [-Wchar-subscripts]
44 | if (!pool[cur].next[c]) {
| ^
palindrome.cpp:45:19: warning: array subscript has type 'char' [-Wchar-subscripts]
45 | pool[cur].next[c] = new_node;
| ^
palindrome.cpp:55:25: warning: array subscript has type 'char' [-Wchar-subscripts]
55 | int q = pool[cur].next[c];
| ^
palindrome.cpp:66:31: warning: array subscript has type 'char' [-Wchar-subscripts]
66 | while (cur && pool[cur].next[c] == q) {
| ^
palindrome.cpp:67:18: warning: array subscript has type 'char' [-Wchar-subscripts]
67 | pool[cur].next[c] = clone;
| ^
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
0 ms |
340 KB |
Output is correct |
2 |
Correct |
0 ms |
340 KB |
Output is correct |
3 |
Correct |
0 ms |
340 KB |
Output is correct |
4 |
Correct |
1 ms |
340 KB |
Output is correct |
5 |
Correct |
0 ms |
340 KB |
Output is correct |
6 |
Correct |
1 ms |
340 KB |
Output is correct |
7 |
Correct |
0 ms |
340 KB |
Output is correct |
8 |
Correct |
0 ms |
340 KB |
Output is correct |
9 |
Correct |
0 ms |
340 KB |
Output is correct |
10 |
Correct |
1 ms |
340 KB |
Output is correct |
11 |
Correct |
0 ms |
340 KB |
Output is correct |
12 |
Correct |
0 ms |
340 KB |
Output is correct |
13 |
Correct |
0 ms |
340 KB |
Output is correct |
14 |
Correct |
0 ms |
340 KB |
Output is correct |
15 |
Correct |
0 ms |
340 KB |
Output is correct |
16 |
Correct |
0 ms |
340 KB |
Output is correct |
17 |
Correct |
1 ms |
340 KB |
Output is correct |
18 |
Correct |
1 ms |
340 KB |
Output is correct |
19 |
Correct |
0 ms |
340 KB |
Output is correct |
20 |
Correct |
1 ms |
340 KB |
Output is correct |
21 |
Correct |
1 ms |
340 KB |
Output is correct |
22 |
Correct |
1 ms |
384 KB |
Output is correct |
23 |
Correct |
1 ms |
296 KB |
Output is correct |
24 |
Correct |
1 ms |
340 KB |
Output is correct |
25 |
Correct |
0 ms |
340 KB |
Output is correct |
26 |
Correct |
0 ms |
340 KB |
Output is correct |
27 |
Correct |
1 ms |
340 KB |
Output is correct |
28 |
Correct |
0 ms |
340 KB |
Output is correct |
29 |
Correct |
1 ms |
340 KB |
Output is correct |
30 |
Correct |
0 ms |
340 KB |
Output is correct |
31 |
Correct |
1 ms |
340 KB |
Output is correct |
32 |
Correct |
1 ms |
340 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
468 KB |
Output is correct |
2 |
Correct |
1 ms |
468 KB |
Output is correct |
3 |
Correct |
1 ms |
468 KB |
Output is correct |
4 |
Correct |
1 ms |
468 KB |
Output is correct |
5 |
Correct |
1 ms |
468 KB |
Output is correct |
6 |
Correct |
1 ms |
468 KB |
Output is correct |
7 |
Correct |
1 ms |
468 KB |
Output is correct |
8 |
Correct |
1 ms |
468 KB |
Output is correct |
9 |
Correct |
1 ms |
468 KB |
Output is correct |
10 |
Correct |
1 ms |
468 KB |
Output is correct |
11 |
Correct |
1 ms |
468 KB |
Output is correct |
12 |
Correct |
1 ms |
468 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
1748 KB |
Output is correct |
2 |
Correct |
3 ms |
2772 KB |
Output is correct |
3 |
Correct |
2 ms |
1748 KB |
Output is correct |
4 |
Correct |
3 ms |
2772 KB |
Output is correct |
5 |
Correct |
2 ms |
1748 KB |
Output is correct |
6 |
Correct |
3 ms |
2560 KB |
Output is correct |
7 |
Correct |
4 ms |
2928 KB |
Output is correct |
8 |
Correct |
2 ms |
2004 KB |
Output is correct |
9 |
Correct |
3 ms |
2004 KB |
Output is correct |
10 |
Correct |
2 ms |
2132 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
14 ms |
14000 KB |
Output is correct |
2 |
Correct |
31 ms |
19164 KB |
Output is correct |
3 |
Correct |
13 ms |
13968 KB |
Output is correct |
4 |
Correct |
31 ms |
18404 KB |
Output is correct |
5 |
Correct |
14 ms |
13968 KB |
Output is correct |
6 |
Correct |
25 ms |
18528 KB |
Output is correct |
7 |
Correct |
37 ms |
23320 KB |
Output is correct |
8 |
Correct |
35 ms |
17256 KB |
Output is correct |
9 |
Correct |
32 ms |
19504 KB |
Output is correct |
10 |
Correct |
32 ms |
20108 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
44 ms |
40780 KB |
Output is correct |
2 |
Correct |
111 ms |
72748 KB |
Output is correct |
3 |
Correct |
46 ms |
41056 KB |
Output is correct |
4 |
Correct |
103 ms |
65024 KB |
Output is correct |
5 |
Correct |
52 ms |
41068 KB |
Output is correct |
6 |
Correct |
110 ms |
67416 KB |
Output is correct |
7 |
Correct |
148 ms |
73900 KB |
Output is correct |
8 |
Correct |
144 ms |
51296 KB |
Output is correct |
9 |
Correct |
127 ms |
51320 KB |
Output is correct |
10 |
Correct |
91 ms |
56956 KB |
Output is correct |
11 |
Correct |
50 ms |
41072 KB |
Output is correct |
12 |
Correct |
119 ms |
53456 KB |
Output is correct |