#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
using ll = long long;
using ii = pair<int, int>;
using aa = array<int,4>;
const int N = 50005;
const ll INF = 1e18;
const ll MOD = 1e9+7;
const int base = 311;
int n, u, v, root, mid, mx = 0, ans = 1;
ll x, y;
//hashing
ll a[N];
//centroid
int sz[N];
bool num[N];
// tree
char c;
vector <int> adj[N];
//answer
bool ok;
map<ll,bool> mp[N];
int getSize(int u,int p){
sz[u] = 1;
for (int it : adj[u]){
if (it == p || num[it]) continue;
sz[u] += getSize(it,u);
}
return sz[u];
}
int getCentroid(int u,int p,int n){
for (int it : adj[u]){
if (it == p || num[it]) continue;
if (sz[it] * 2 > n) return getCentroid(it,u,n);
}
return u;
}
ll binpow(ll a,ll b){
ll res = 1;
while (b > 0){
if (b & 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
void dfs(int u,int p,ll xuoi,ll nguoc,int type,int depth){
if (depth > mid - type) return;
/*
x1 + y2 * base |x1| = x2 + y1 * base |x2|
x1 - y1 * base ^ (mid - |x1|) = x2 - y2 * base ^ |x1|
|x1| ở đây là depth
*/
ll val = (xuoi - (nguoc * binpow(base,mid - depth) % MOD) + MOD) % MOD;
if (!type){
if (mp[mid - depth].count(val) > 0){
ok = 1;
return;
}
} else{
mx = max(mx,depth);
mp[depth][val] = 1;
}
for (int it : adj[u]){
if (it == p || num[it]) continue;
x = (xuoi * base + a[it]) % MOD;
y = (nguoc + a[it] * binpow(base,depth)) % MOD;
dfs(it,u,x,y,type,depth + 1);
}
}
void decompose(int u){
root = getCentroid(u,0,getSize(u,0));
num[root] = 1;
mx = 0;
mp[0][0] = 1;
for (int it : adj[root]){
if (num[it]) continue;
dfs(it,root,a[root] * base + a[it],a[it] * base + a[root],0,2);
if (ok){
for (int i = 1; i <= mx; i++){
mp[i].clear();
}
return;
}
dfs(it,root,a[it],a[it],1,1);
}
for (int i = 1; i <= mx; i++){
mp[i].clear();
}
for (int it : adj[root]){
if (num[it]) continue;
decompose(it);
}
}
bool check(){
ok = 0;
for (int i = 1; i <= n; i++) num[i] = 0;
decompose(1);
return ok;
}
signed main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n;
for (int i = 1; i <= n; i++){
cin >> c;
a[i] = (c - 'a' + 1);
}
for (int i = 1; i < n; i++){
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
int l = 1, r = n / 2;
while (l <= r){
mid = (l + r) >> 1;
mid <<= 1;
if (check()){
ans = mid;
l = (mid >> 1) + 1;
} else r = (mid >> 1) - 1;
}
l = ans / 2 + 1, r = (n + 1) / 2;
while (l <= r){
mid = (l + r) >> 1;
mid = (mid << 1) - 1;
if (check()){
ans = max(ans,mid);
l = ((mid + 1) >> 1) + 1;
} else r = ((mid + 1) >> 1) - 1;
}
cout << ans;
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |