#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
//using namespace __gnu_pbds;
#define LongDepTrai "lampice"
#define ll long long
#define ull unsigned long long
#define ld long double
#define ii pair<int,int>
#define iii pair<int,ii>
#define iv pair<ii,ii>
#define pll pair<ll,ll>
#define vi vector<int>
#define vii vector<ii>
#define vll vector<ll>
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) int((x).size())
#define order_set(T) tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>
inline ll add(ll a, ll b, ll mod){ a += b; if(a >= mod) a -= mod; return a; }
inline ll sub(ll a, ll b, ll mod){ a -= b; if(a < 0) a += mod; return a; }
inline ll mul(ll a, ll b, ll mod){ return ( (ll)a * b ) % mod; }
static mt19937_64 rng((unsigned)chrono::steady_clock::now().time_since_epoch().count());
const int N=5e4+9;
const int base=341;
const int mod=1e9+7;
string s;
//hash1[v]=(hash1[u]*base+(c[v]-'a')+1)%mod.
//hash2[v]=((c[v]-'a')+1+hash2[u]*Pow[1])%mod)%mod.
//hash2[u]*Pow[k-h[u]]-hash1[u]==hash2[v]*Pow[k-h[v]]-hash1[v].
ll Pow[N];
int n,sz[N],k,timer=0,del[N],res[N],h[N],tin[N],tout[N],tour[N];
unordered_map<ll,bool> cnt[N];
vi g[N];
void dfs(int u,int p){
sz[u]=1;
for(int x:g[u]){
if(x==p) continue;
if(del[x]) continue;
dfs(x,u);
sz[u]+=sz[x];
}
}
int FindCentroid(int u,int p,int root){
for(int x:g[u]){
if(x==p) continue;
if(del[x]) continue;
if(sz[x]>sz[root]/2) {
return FindCentroid(x,u,root);
}
}
return u;
}
vector<pair<int,ll>> ups;
int mxUpd=0;
bool cal(int u,int p,int h,ll hash1,ll hash2,int len){
if(h>len) return 0;
if(p!=-1) hash1=(hash1*base+(s[u]-'a')+1)%mod;
hash2=(((s[u]-'a')+1)*Pow[h-1]%mod+hash2)%mod;
ll x=(hash2*Pow[len-h]%mod-hash1+mod)%mod;
if(p==-1) cnt[h][x]=1;
if(cnt[len-h+1].find(x)!=cnt[len-h+1].end()){
return 1;
}
for(int x:g[u]){
if(p==-1) ups.clear();
if(x==p) continue;
if(del[x]) continue;
if(cal(x,u,h+1,hash1,hash2,len)){
return 1;
}
if(p==-1)
for(pair<int,ll> vy:ups){
cnt[vy.fi][vy.se]=1;
}
}
mxUpd=max(mxUpd,h);
ups.pb({h,x});
return 0;
}
bool solve(int k,int u){
dfs(u,-1);
int x=FindCentroid(u,-1,u);
bool ans=0;
mxUpd=0;
ans=cal(x,-1,1,0,0,k);
if(ans==1) return ans;
for(int i=1;i<=mxUpd;i++) cnt[i].clear();
mxUpd=0;
del[x]=1;
for(int v:g[x]){
if(del[v]) continue;
if(solve(k,v)==1) return 1;
}
return 0;
}
bool check(int k){
for(int i=1;i<=n;i++) del[i]=0,cnt[i].clear();
return solve(k,1);
}
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
if(fopen(LongDepTrai".inp","r")){
freopen(LongDepTrai".inp","r",stdin);
freopen(LongDepTrai".out","w",stdout);
}
cin>>n;
cin>>s;
int lenT=s.size();
s=" "+s;
Pow[0]=1;
for(int i=1;i<=lenT;i++){
Pow[i]=(Pow[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=1,r=(n-1)/2;
int res=1;
while(l<=r){
int mid=(l+r)/2;
if(check(2*mid+1)){
res=max(res,mid*2+1);
l=mid+1;
}
else{
r=mid-1;
}
}
l=1,r=n/2;
while(l<=r){
int mid=(l+r)/2;
if(check(2*mid)){
res=max(res,mid*2);
l=mid+1;
}
else{
r=mid-1;
}
}
cout<<res;
return 0;
}
Compilation message (stderr)
lampice.cpp: In function 'int main()':
lampice.cpp:112:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
112 | freopen(LongDepTrai".inp","r",stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lampice.cpp:113:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
113 | freopen(LongDepTrai".out","w",stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |