This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define all(g) g.begin(), g.end()
#define rall(g) g.rbegin(), g.rend()
using ll = long long;
using ld = long double;
void solve(int T);
void pre();
const int N = 5e4 + 5;
const int M = 405;
const int SQRT = 500;
const int LOG = 20;
const int INF = 1e18;
const int MOD = 1e9 + 7;
const ld EPS = 1e-9;
const int BASE = 9973;
void pre(){
ios::sync_with_stdio(false);
cin.tie(0);
}
int32_t main(){
pre();
int tt = 1;
//cin>>tt;
for(int i = 1;i<=tt;i++){
cerr<<"Case "<<i<<": "<<endl;
solve(i);
}
return 0;
}
int n, m, h;
int color[N];
int po[N];
int curlen, cursz;
int sz[N], curdn[N];
int up[N], down[N], dep[N];
vector<int> g[N];
bool del[N];
bool ispal[N];
bool bb;
set<int> hashes_s, hashes_l;
vector<int> toadd_s, toadd_l;
int fh(int dx, int dy, int hx, int hy){
int dif = dy - dx;
return (hy - (hx * po[dif]) % MOD + 2 * MOD) % MOD;
}
void dfs(int x, int p){
sz[x] = 1;
for(int u : g[x]){
if(u == p || del[u])continue;
dfs(u, x);
sz[x] += sz[u];
}
}
int cen(int x, int p){
for(int u : g[x]){
if(del[u] || u == p)continue;
if(sz[u] * 2 > cursz)return cen(u, x);
}
return x;
}
void dfs2(int x, int p){
if(bb)return;
if(dep[x] > curlen)return;
down[x] = (down[p] * BASE + color[x]) % MOD;
up[x] = (up[p] + po[dep[x]] * color[x]) % MOD;
curdn[dep[x]] = x;
ispal[x] = (up[x] == down[x]);
if(dep[x] == curlen){
if(ispal[x])bb = true;
}
else if(dep[x] > curlen / 2){
int dif = 2 * dep[x] - curlen;
int c = curdn[dif];
int pc = curdn[dif - 1];
if(ispal[c]){
int hn = fh(dep[c] - 1, dep[x], down[pc], down[x]);
if(hashes_s.count(hn))bb = true;
toadd_l.pb(hn);
}
}
else {
if(hashes_l.count(down[x])){
bb = true;
}
toadd_s.pb(down[x]);
}
if(dep[x] * 2 == curlen){
if(hashes_s.count(down[x]))bb = true;
}
for(int u : g[x]){
if(del[u] || u == p)continue;
dep[u] = dep[x] + 1;
dfs2(u, x);
}
}
void decomp(int x){
if(bb)return;
dfs(x, 0);
cursz = sz[x];
int C = cen(x, 0);
dep[C] = 0;
up[C] = down[C] = color[C];
del[C] = 1;
curdn[0] = C;
for(int u : g[C]){
if(!del[u]){
dep[u] = 1;
dfs2(u, C);
while(toadd_s.size()){
int t = toadd_s.back();
toadd_s.pop_back();
hashes_s.insert(t);
}
while(toadd_l.size()){
int t = toadd_l.back();
toadd_l.pop_back();
hashes_l.insert(t);
}
}
}
hashes_s.clear();
hashes_l.clear();
for(int u : g[C]){
if(!del[u]){
decomp(u);
}
}
}
bool ok(int x){
if(x == 1)return 1;
curlen = x - 1;
memset(del, 0, n + 1);
bb = 0;
decomp(1);
return bb;
}
void solve(int T){
cin>>n;
string s;
cin>>s;
for(int i = 0;i<n;i++){
color[i + 1] = s[i] - 'a' + 1;
}
po[0] = 1;
for(int i = 1;i<=n;i++)po[i] = (po[i - 1] * BASE) % MOD;
for(int i = 1;i<n;i++){
int u,v;
cin>>u>>v;
g[u].pb(v);
g[v].pb(u);
}
int l = 0;
int r = n / 2 - (n % 2 == 0);
int ans=0;
while(r >= l){
int mid = (r + l) / 2;
if(ok(mid * 2 + 1)){
ans = max(ans, mid * 2 + 1);
l = mid + 1;
}
else {
r = mid - 1;
}
}
l = ans / 2 + 1;
r = n / 2;
while(r >= l){
int mid = (r + l) / 2;
if(ok(mid * 2)){
ans = max(ans, mid * 2);
l = mid + 1;
}
else {
r = mid - 1;
}
}
cout<<ans;
}
# | 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... |