Submission #1129501

#TimeUsernameProblemLanguageResultExecution timeMemory
1129501NonozeLampice (COCI19_lampice)C++20
0 / 110
4658 ms10952 KiB
/* * Author: Nonoze * Created: Tuesday 24/12/2024 */ #include <bits/stdc++.h> using namespace std; #ifndef _IN_LOCAL #define dbg(...) #endif #define endl '\n' #define endlfl '\n' << flush #define quit(x) return (void)(cout << x << endl) template<typename T> void read(T& x) { cin >> x;} template<typename T1, typename T2> void read(pair<T1, T2>& p) { read(p.first), read(p.second);} template<typename T> void read(vector<T>& v) { for (auto& x : v) read(x); } template<typename T1, typename T2> void read(T1& x, T2& y) { read(x), read(y); } template<typename T1, typename T2, typename T3> void read(T1& x, T2& y, T3& z) { read(x), read(y), read(z); } template<typename T1, typename T2, typename T3, typename T4> void read(T1& x, T2& y, T3& z, T4& zz) { read(x), read(y), read(z), read(zz); } template<typename T> void print(vector<T>& v) { for (auto& x : v) cout << x << ' '; cout << endl; } #define sz(x) (int)(x.size()) #define all(x) (x).begin(), (x).end() #define rall(x) (x).rbegin(), (x).rend() #define make_unique(v) sort(all(v)), v.erase(unique(all(v)), (v).end()) #define pb push_back #define mp(a, b) make_pair(a, b) #define fi first #define se second #define cmin(a, b) a = min(a, b) #define cmax(a, b) a = max(a, b) #define YES cout << "YES" << endl #define NO cout << "NO" << endl #define QYES quit("YES") #define QNO quit("NO") #define int long long #define double long double const int inf = numeric_limits<int>::max() / 4; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int MOD = 1e9+7, LOG=20; void solve(); signed main() { ios::sync_with_stdio(0); cin.tie(0); int tt=1; // cin >> tt; while(tt--) solve(); return 0; } int A=27, B=1e9+7; int fastpow(int x, int y) { if (!y) return 1; int z = fastpow(x, y/2); z = z*z % MOD; if (y&1) z = z*x % MOD; return z; } int inv(int x) { return fastpow(x, MOD-2); } int n, k, m, q; vector<int> a; vector<vector<int>> adj; vector<int> sz, centroid, child; map<pair<int, int>, bool> cnt; int obj; bool works; void dfs(int u, int p=-1) { sz[u]=1; for (auto v: adj[u]) if (v!=p && !centroid[v]) { dfs(v, u); sz[u]+=sz[v]; } } int get_centroid(int u, int p, int tot) { for (auto v: adj[u]) if (v!=p && !centroid[v] && sz[v]*2>tot) return get_centroid(v, u, tot); return u; } void fill(int u, int p, int d, int hashminus, int hashplus, bool filling, int cur) { if (d>obj*2) return; int hash=(hashplus-hashminus+MOD)%MOD; if (d<obj) hash*=fastpow(A, obj-d); if (filling) { cnt[{d, hash}]=1; } else if (cnt.count({obj*2-d, hash})) { works=1; } // cout << hash << ' ' << d << ' ' << filling << endl; // cout << hashminus << ' ' << hashplus << endl; int newcur=cur; if (d>=obj) newcur=child[cur]; for (auto v: adj[u]) if (v!=p && !centroid[v]) { int newhashminus = (hashminus*A)%MOD; int newhashplus = hashplus + fastpow(A, min(obj, d))*a[v]; if (d>=obj) { newhashminus=(newhashminus+a[cur])%MOD; newhashplus=((newhashplus-a[cur]+MOD)*inv(A))%MOD; } child[u]=v; fill(v, u, d+1, newhashminus, newhashplus, filling, newcur); } } void fill2(int u, int p, int d, int hashminus, int hashplus, bool filling, int cur) { if (d>obj*2+1) return; int hash=(hashplus-hashminus+MOD)%MOD; if (d<obj) hash*=fastpow(A, obj-d); if (filling) { cnt[{d, hash}]=1; } else if (cnt.count({obj*2+1-d, hash})) { works=1; } // cout << hashminus << ' ' << hashplus << ' ' << hash << ' ' << d << ' ' << filling << ' ' << cur+1 << endl; int newcur=cur; if (d>=obj) newcur=child[cur]; for (auto v: adj[u]) if (v!=p && !centroid[v]) { int newhashminus = (hashminus*A)%MOD; int newhashplus = hashplus + fastpow(A, min(obj, d))*a[v]; if (d>=obj) { if (d>obj) newhashminus=(newhashminus+a[cur])%MOD; // cout << newhashplus << ' ' << a[child[cur]] << ' ' << child[cur] << endl; newhashplus=(((newhashplus-a[child[cur]]+MOD)%MOD)*inv(A))%MOD; } child[u]=v; fill2(v, u, d+1, newhashminus, newhashplus, filling, newcur); } } void decompo(int u, bool pair, int p=-1) { dfs(u); int c=get_centroid(u, -1, sz[u]); centroid[c]=1; cnt.clear(); cnt[{1, (a[c]*fastpow(A, obj-1))%MOD}]=1; // cout << (a[c]*fastpow(A, obj-1))%MOD << endl; for (auto v: adj[c]) if (!centroid[v]) { if (pair) { child[c]=v; fill(v, c, 1, 0, a[v], 0, v); fill(v, c, 2, 0, a[c]+A*a[v], 1, c); } else { child[n]=c, child[c]=v; fill2(v, c, 1, 0, a[v], 0, c); fill2(v, c, 2, 0, (obj>1?a[c]+A*a[v]:a[v]), 1, (obj>1?n:c)); } // cout << endl; } // cout << "OK " << c+1 << endl; for (auto v: adj[c]) if (!centroid[v]) decompo(v, pair, c); } void solve() { read(n); a.clear(), a.resize(n); for (auto& u: a) { char x; cin >> x; u=x-'a'+1; } adj.clear(), adj.resize(n), child.clear(), child.resize(n+1); int l=2, r=n/2, ans=1; for (int i=1; i<n; i++) { int u, v; read(u, v); u--, v--; adj[u].pb(v), adj[v].pb(u); if (a[u]==a[v]) ans=2; } while (l<=r) { int mid=(l+r)/2; works=0, obj=mid, sz.clear(), sz.resize(n), centroid.clear(), centroid.resize(n); decompo(0, 1); if (works) ans=mid*2, l=mid+1; else r=mid-1; } l=1, r=(n-(1-n%2))/2; while (l<=r) { int mid=(l+r)/2; works=0, obj=mid, sz.clear(), sz.resize(n), centroid.clear(), centroid.resize(n); decompo(0, 0); if (works) cmax(ans, mid*2+1), l=mid+1; else r=mid-1; } cout << ans << endl; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...