Submission #844078

#TimeUsernameProblemLanguageResultExecution timeMemory
844078CaubethieunangLampice (COCI19_lampice)C++17
110 / 110
2274 ms21500 KiB
#include <bits/stdc++.h> #define ll long long #define LOG 20 #define MASK(i) (1LL<<(i)) #define BIT(x,i) (((x)>>(i))&1) #define FIRST_BIT(mask) __builtin_ctz((mask)&(-mask)) #define ERASE_BIT(mask) (mask)^((mask)&(-mask)) #define left _left #define right _right #define task "t" using namespace std; const ll INF=1e18; const int iat=1e5+9; const int mod=1e9+7; const int base=31; void fast_IO() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); if(fopen(task".inp","r")) { freopen(task".inp","r",stdin); freopen(task".out","w",stdout); } } int n; char s[iat]; vector <int> g[iat],node; int child[iat],dep[iat],f[iat][LOG]; bool visited[iat],res; ll pw[iat],HashUp[iat],HashDown[iat]; vector <pair<ll,int>> store[iat]; void dfs(int u, int par) { child[u]=1; for(auto v : g[u]) { if(v!=par && !visited[v])dfs(v,u),child[u]+=child[v]; } } int centroid(int u, int par, int sz) { for(auto v : g[u]) { if(v!=par && !visited[v]) { if(child[v]>sz/2)return centroid(v,u,sz); } } return u; } void calc(int u, int par) { node.push_back(u); store[dep[u]].push_back(make_pair(HashDown[u],u)); for(int i=1; MASK(i)<=n; i++)f[u][i]=f[f[u][i-1]][i-1]; for(int v : g[u]) { if(v!=par && !visited[v]) { f[v][0]=u; dep[v]=dep[u]+1; HashDown[v]=HashDown[u]*base+s[v]-'a'+1; HashUp[v]=HashUp[u]+pw[dep[v]-1]*(s[v]-'a'+1); calc(v,u); } } } int lift(int x, int k) { for(int i=LOG-1; i>=0; i--) { if(BIT(k,i))x=f[x][i]; } return x; } int LCA(int u, int v) { if(u==v)return u; if(dep[u]<dep[v])swap(u,v); int k=dep[u]-dep[v]; for(int i=LOG-1; i>=0; i--) { if(BIT(k,i))u=f[u][i]; } if(u==v)return u; for(int i=LOG-1; i>=0; i--) { if(f[u][i]!=f[v][i])u=f[u][i],v=f[v][i]; } return f[u][0]; } ll GetHash(int u, int v) { return HashDown[u]-HashDown[f[v][0]]*pw[dep[u]-dep[v]+1]; } void solve(int u, int len) { if(res)return; HashUp[u]=s[u]-'a'+1; HashDown[u]=s[u]-'a'+1; node.clear(); f[u][0]=0,dep[u]=1; calc(u,u); for(int i=1; i<=n; i++) { if(store[i].empty())break; sort(store[i].begin(),store[i].end()); } for(int it : node) { if(res)break; int dneed=len-dep[it]+1; if(dneed>dep[it] || dneed<1)continue; int X=lift(it,dneed-1); if(HashDown[X]!=HashUp[X])continue; ll tmp=GetHash(it,X); int l=lower_bound(store[dneed].begin(),store[dneed].end(),make_pair(tmp,-1))-store[dneed].begin(); if(l==store[dneed].size() || store[dneed][l].first!=tmp)continue; while(l<store[dneed].size()) { if(store[dneed][l].first!=tmp)break; if(LCA(it,store[dneed][l].second)==u) { res=true; break; } l++; } } for(int i=1; i<=n; i++) { if(store[i].empty())break; store[i].clear(); } } void build_tree(int u, int len) { if(res)return; dfs(u,u); int x=centroid(u,u,child[u]); visited[x]=true; solve(x,len); for(int v : g[x]) { if(!visited[v])build_tree(v,len); } } bool check(int x) { for(int i=1; i<=n; i++)visited[i]=false; res=false; build_tree(1,x); return res; } signed main() { fast_IO(); cin>>n; pw[0]=1; for(int i=1; i<=n; i++)pw[i]=pw[i-1]*base; for(int i=1; i<=n; i++)cin>>s[i]; for(int i=1; i<n; i++) { int a,b; cin>>a>>b; g[a].push_back(b); g[b].push_back(a); } int ans=1; int l=1,r=n/2; while(l<=r) { int mid=(l+r)/2; int val=mid*2+1; if(check(val))ans=max(ans,val),l=mid+1; else r=mid-1; } l=1,r=n/2; while(l<=r) { int mid=(l+r)/2; int val=mid*2; if(check(val))ans=max(ans,val),l=mid+1; else r=mid-1; } cout<<ans; }

Compilation message (stderr)

lampice.cpp: In function 'void solve(int, int)':
lampice.cpp:120:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  120 |         if(l==store[dneed].size() || store[dneed][l].first!=tmp)continue;
      |            ~^~~~~~~~~~~~~~~~~~~~~
lampice.cpp:121:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<std::pair<long long int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  121 |         while(l<store[dneed].size())
      |               ~^~~~~~~~~~~~~~~~~~~~
lampice.cpp: In function 'void fast_IO()':
lampice.cpp:23:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   23 |         freopen(task".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
lampice.cpp:24:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   24 |         freopen(task".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...