#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 5e4 + 5, mod = 1e9 + 7, base = 31;
unordered_set<int> mp, existed;
int xuoi[N], nguoc[N], pw[N];
int dpt[N], up[N], sz[N];
bool rem[N], checked;
vector <int> adj[N];
int ans = 1, n, r;
char a[N];
int add(int value, char x) {
return (value * base + x - 'a' + 1);
}
int dfs(int x, int p) {
sz[x] = 1;
for (int y: adj[x]) {
if (y == p || rem[y]) continue;
sz[x] += dfs(y, x);
}
return sz[x];
}
void down(int x, int p, int len) {
dpt[x] = dpt[p] + 1;
up[dpt[x]] = x;
if (dpt[x] >= len || checked) return;
int curlen = dpt[x] + 1;
if (curlen == len) {
///centroid->con
///xuoi == nguoc
int Xuoi = xuoi[x] + (a[r] - 'a' + 1) * pw[dpt[x]];
int Nguoc = nguoc[x] * base + (a[r] - 'a' + 1);
if (Xuoi == Nguoc) return checked = 1, void();
}
mp.insert(xuoi[x]);
for (int y: adj[x]) {
if (y == p || rem[y]) continue;
xuoi[y] = add(xuoi[x], a[y]);
nguoc[y] = nguoc[x] + (a[y] - 'a' + 1) * pw[dpt[x]];
down(y, x, len);
}
if (checked) return;
if (curlen >= (len + 1) / 2) {
int xx = len - curlen;
if (xx <= curlen) {
///curstr[curlen-1,...,curlen-x]..curstr
if (xx > dpt[x]) return;
int chaxet = up[dpt[x] - xx]; //jump(x,xx);///log
int Xuoi = xuoi[chaxet] + (a[r] - 'a' + 1) * pw[dpt[chaxet]];
int Nguoc = nguoc[chaxet] * base + (a[r] - 'a' + 1);
if (Xuoi != Nguoc) return;
int suffix = xuoi[x] - xuoi[chaxet] * pw[xx];
if (existed.find(suffix) != existed.end())
return checked = 1, void();
}
}
}
bool ok(int x, int len) {
if (sz[x] < len) return 0;
if (len <= 1) return 1;
dpt[x] = 0;
xuoi[x] = nguoc[x] = 0;
r = x;
existed.clear();
checked = 0;
for (int y: adj[x]) {
if (rem[y]) continue;
mp.clear();
xuoi[y] = nguoc[y] = a[y] - 'a' + 1;
down(y, x, len);
for (int x: mp)
existed.insert(x);
}
return checked;
}
void sus(int x, int p) {
sz[x] = 1;
for (int y: adj[x]) {
if (y == p || rem[y]) continue;
sus(y, x);
sz[x] += sz[y];
}
}
void solve(int x) {
{
///chan
int l = ans / 2, r = sz[x];
while (l <= r) {
int mid = (l + r) / 2;
if (ok(x, mid * 2)) {
ans = max(ans, mid * 2);
l = mid + 1;
} else r = mid - 1;
}
}
{
///le
int l = ans / 2, r = sz[x];
while (l <= r) {
int mid = (l + r) / 2;
if (ok(x, mid * 2 + 1)) {
ans = max(ans, mid * 2 + 1);
l = mid + 1;
} else r = mid - 1;
}
}
reverse(adj[x].begin(), adj[x].end());
}
int find_centroid(int x, int p, int tot) {
for (int y: adj[x])
if (y != p && !rem[y] && sz[y] > tot / 2)
return find_centroid(y, x, tot);
return x;
}
void build(int x = 1) {
int c = find_centroid(x, 0, dfs(x, 0));
rem[c] = 1;
sus(c, 0);
solve(c);
solve(c);
for (int y: adj[c])
if (!rem[y])
build(y);
}
int32_t main() {
cin.tie(0)->sync_with_stdio(0);
cin >> n;
pw[0] = 1;
for (int i = 1; i <= n; i++) pw[i] = 1ll * pw[i - 1] * base;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i < n; i++) {
int x, y;
cin >> x >> y;
adj[x].push_back(y);
adj[y].push_back(x);
}
build();
cout << ans;
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2648 KB |
Output is correct |
2 |
Correct |
4 ms |
2652 KB |
Output is correct |
3 |
Correct |
13 ms |
2652 KB |
Output is correct |
4 |
Correct |
10 ms |
2808 KB |
Output is correct |
5 |
Correct |
1 ms |
2396 KB |
Output is correct |
6 |
Correct |
1 ms |
2652 KB |
Output is correct |
7 |
Correct |
1 ms |
2652 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1201 ms |
10680 KB |
Output is correct |
2 |
Correct |
540 ms |
10940 KB |
Output is correct |
3 |
Correct |
161 ms |
10932 KB |
Output is correct |
4 |
Correct |
166 ms |
11204 KB |
Output is correct |
5 |
Correct |
396 ms |
11700 KB |
Output is correct |
6 |
Correct |
37 ms |
10420 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1500 ms |
8624 KB |
Output is correct |
2 |
Correct |
846 ms |
8348 KB |
Output is correct |
3 |
Correct |
810 ms |
8632 KB |
Output is correct |
4 |
Correct |
491 ms |
7540 KB |
Output is correct |
5 |
Correct |
593 ms |
7852 KB |
Output is correct |
6 |
Correct |
688 ms |
7084 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
2 ms |
2648 KB |
Output is correct |
2 |
Correct |
4 ms |
2652 KB |
Output is correct |
3 |
Correct |
13 ms |
2652 KB |
Output is correct |
4 |
Correct |
10 ms |
2808 KB |
Output is correct |
5 |
Correct |
1 ms |
2396 KB |
Output is correct |
6 |
Correct |
1 ms |
2652 KB |
Output is correct |
7 |
Correct |
1 ms |
2652 KB |
Output is correct |
8 |
Correct |
1201 ms |
10680 KB |
Output is correct |
9 |
Correct |
540 ms |
10940 KB |
Output is correct |
10 |
Correct |
161 ms |
10932 KB |
Output is correct |
11 |
Correct |
166 ms |
11204 KB |
Output is correct |
12 |
Correct |
396 ms |
11700 KB |
Output is correct |
13 |
Correct |
37 ms |
10420 KB |
Output is correct |
14 |
Correct |
1500 ms |
8624 KB |
Output is correct |
15 |
Correct |
846 ms |
8348 KB |
Output is correct |
16 |
Correct |
810 ms |
8632 KB |
Output is correct |
17 |
Correct |
491 ms |
7540 KB |
Output is correct |
18 |
Correct |
593 ms |
7852 KB |
Output is correct |
19 |
Correct |
688 ms |
7084 KB |
Output is correct |
20 |
Correct |
848 ms |
5976 KB |
Output is correct |
21 |
Correct |
1345 ms |
6988 KB |
Output is correct |
22 |
Correct |
1311 ms |
8276 KB |
Output is correct |
23 |
Correct |
383 ms |
5316 KB |
Output is correct |
24 |
Correct |
476 ms |
6492 KB |
Output is correct |
25 |
Correct |
457 ms |
6108 KB |
Output is correct |
26 |
Correct |
1040 ms |
8108 KB |
Output is correct |
27 |
Correct |
2439 ms |
8376 KB |
Output is correct |
28 |
Correct |
534 ms |
5220 KB |
Output is correct |
29 |
Correct |
569 ms |
5208 KB |
Output is correct |
30 |
Correct |
520 ms |
7004 KB |
Output is correct |
31 |
Correct |
591 ms |
5724 KB |
Output is correct |
32 |
Correct |
334 ms |
8280 KB |
Output is correct |
33 |
Correct |
796 ms |
7192 KB |
Output is correct |