#include <bits/stdc++.h>
using namespace std;
#define TRACE(x) cerr << #x << " :: " << x << endl
#define _ << " " <<
#define SZ(x) (int)(x).size()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define RFOR(i,a,b) for (int i=(a);i>=(b);--i)
const int MX_N = 5e4+5;
int N;
string S;
vector<int> al[MX_N];
const int P = 31337;//, Q = 1e9+7;
int pp[MX_N];
void init_hashing() {
pp[0] = 1;
FOR(i,1,N) pp[i] = 1LL*pp[i-1]*P;
}
int sub[MX_N], dad[MX_N];
int subtree(int u, int p) {
sub[u] = 1;
for (auto v : al[u]) if (dad[v] == -1 and v != p) {
sub[u] += subtree(v, u);
}
return sub[u];
}
int centroid(int u, int p, int sz) {
for (auto v : al[u]) if (dad[v] == -1 and v != p and sub[v] > sz/2) {
return centroid(v, u, sz);
}
return u;
}
int dist[MX_N], hu[MX_N], hd[MX_N];
vector<int> nodes;
void dfs(int u, int p, int r, int d=0) {
nodes.push_back(u);
dist[u] = d;
hu[u] = (hu[p] + 1LL * pp[dist[u]] * (S[u]-96));
hd[u] = (1LL * hd[p] * P + (S[u]-96));
//TRACE("dfs" _ u _ hu[u] _ hd[u] _ d);
for (int v : al[u]) if (v != p and dad[v] == -1) {
dfs(v,u,r,d+1);
}
}
bool found;
void decomp(int u, int p, int len) {
int sz = subtree(u, p);
int c = centroid(u, p, sz);
dad[c] = p;
map<int,set<int>> hashes;
for (auto v : al[c]) if (dad[v] == -1) {
nodes.clear();
dfs(v,c,c);
//TRACE(c _ SZ(nodes));
vector<pair<int,int>> tmp;
for (int x : nodes) {
//TRACE(x _ dist[x]+2);
if (dist[x]+2 > len) continue;
else if (dist[x]+2 == len) {
int h1 = (1LL * hu[x] * P + (S[c]-96));
int h2 = (hd[x] + 1LL * pp[dist[x]+1] * (S[c]-96));
//TRACE(x _ dist[x] _ h1 _ h2 _ hu[x] _ hd[x]);
//TRACE(dist[x]+1 _ pp[dist[x]+1]);
found |= (h1 == h2);
} else {
int ky = len-1-(dist[x]+1);
int hval = ((1LL * hu[x] * pp[ky + 1] - hd[x]) + 1LL * pp[ky] * (S[c]-96));
//TRACE(x _ dist[x]+1 _ hval _ ky _ "::" _ hu[x] _ hd[x]);
found |= hashes[ky].count(hval) > 0;
tmp.emplace_back(dist[x]+1,hval);
}
}
for (auto x : tmp) {
hashes[x.first].insert(x.second);
}
decomp(v,c,len);
}
}
bool solve(int len) {
found = 0;
memset(dad,-1,sizeof dad);
decomp(1,0,len);
return found;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> N;
cin >> S;
S = "^" + S;
FOR(i,1,N-1){
int A, B; cin >> A >> B;
al[A].push_back(B);
al[B].push_back(A);
}
init_hashing();
int ans = 0;
{ // odd
int lo = 0, hi = (N+1)/2 + 1;
while (hi-lo > 1) {
int mid = (lo+hi)/2;
bool ok = solve(2*mid+1);
if (ok) lo = mid;
else hi = mid;
}
ans = max(ans,2*lo+1);
}
{ // even
int lo = 0, hi = (N+1)/2 + 1;
while (hi-lo > 1) {
int mid = (lo+hi)/2;
bool ok = solve(2*mid);
if (ok) lo = mid;
else hi = mid;
}
ans = max(ans,2*lo);
}
cout << ans << '\n';
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
10 ms |
1792 KB |
Output is correct |
2 |
Correct |
19 ms |
1792 KB |
Output is correct |
3 |
Correct |
57 ms |
2048 KB |
Output is correct |
4 |
Correct |
80 ms |
2048 KB |
Output is correct |
5 |
Correct |
6 ms |
1792 KB |
Output is correct |
6 |
Correct |
5 ms |
1664 KB |
Output is correct |
7 |
Correct |
5 ms |
1664 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
2748 ms |
17372 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
4498 ms |
12596 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
10 ms |
1792 KB |
Output is correct |
2 |
Correct |
19 ms |
1792 KB |
Output is correct |
3 |
Correct |
57 ms |
2048 KB |
Output is correct |
4 |
Correct |
80 ms |
2048 KB |
Output is correct |
5 |
Correct |
6 ms |
1792 KB |
Output is correct |
6 |
Correct |
5 ms |
1664 KB |
Output is correct |
7 |
Correct |
5 ms |
1664 KB |
Output is correct |
8 |
Incorrect |
2748 ms |
17372 KB |
Output isn't correct |
9 |
Halted |
0 ms |
0 KB |
- |