Submission #640683

#TimeUsernameProblemLanguageResultExecution timeMemory
640683LeonaRagingLampice (COCI19_lampice)C++14
110 / 110
4957 ms15104 KiB
#pragma GCC optimize("O3,unroll-loops") #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") #include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; using namespace std; #define fi first #define se second #define ll long long #define pb push_back #define db(val) "[" #val " = " << (val) << "] " const ll mod = 1e9 + 7; const int maxn = 1e5 + 4; const int INF = 1e9; const ll base = 31; const int N = 16; int n, len, root, used[maxn], h[maxn]; string s; vector<int> adj[maxn], nodes; ll Pow[maxn], up[maxn], down[maxn]; gp_hash_table<ll,int> L; bool flag; ll add(ll a, ll b) { a += b; return a; } ll del(ll a, ll b) { a -= b; return a; } void pre(int u, int p) { if (p) down[u] = add(down[p], (s[u] - 'a' + 1) * Pow[h[u] - 1]); if (p) up[u] = add(up[p] * base, s[u] - 'a' + 1); L[up[u]]++; for (int v : adj[u]) if (v != p && !used[v]) { h[v] = h[u] + 1; pre(v, u); } } void dfs(int u, int p) { if (len < h[u] || flag) return; nodes.pb(u); int k = len - h[u] - 1, c = 0; if (int(nodes.size()) > h[u] - k && h[u] - k >= 0) c = nodes[h[u] - k]; if (c && add(up[c], (s[root] - 'a' + 1) * Pow[h[c]]) == add(down[c] * base, (s[root] - 'a' + 1))) { if (k == 0) return flag = true, void(); ll val = del(up[u], up[c] * Pow[k]) ; if (L.find(val) != L.end()) { return flag = true, void(); } } for (int v : adj[u]) if (v != p && !used[v]) dfs(v, u); nodes.pop_back(); } void reset(int u, int p, int val) { L[up[u]] += val; if (L[up[u]] == 0) L.erase(up[u]); for (int v : adj[u]) if (v != p && !used[v]) reset(v, u, val); } void Solve(int c) { h[c] = 0; up[c] = down[c] = 0; L.clear(); pre(c, 0); nodes.clear(); nodes.pb(c); for (int v : adj[c]) if (!used[v]) { if (flag) return; reset(v, c, -1); dfs(v, c); reset(v, c, 1); } nodes.pop_back(); } struct Centroid_Decomposition { int sz[maxn]; int dfs(int u, int p) { sz[u] = 1; for (int v : adj[u]) if (!used[v] && v != p) sz[u] += dfs(v, u); return sz[u]; } int Centroid(int u, int p, int tot) { for (int v : adj[u]) if (!used[v] && v != p && sz[v] > tot / 2) return Centroid(v, u, tot); return u; } void build(int u) { if (flag) return; int c = Centroid(u, 0, dfs(u, 0)); root = c; Solve(c); used[c] = 1; for (int v : adj[c]) if (!used[v]) build(v); } } Cen; bool ok(int m, int sign) { flag = false; len = 2 * m + sign; memset(used, 0, sizeof used); Cen.build(1); return flag; } int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); //freopen(".INP", "r", stdin); //freopen(".OUT", "w", stdout); cin >> n >> s; s = ' ' + s; for (int i = 1; i < n; i++) { int u, v; cin >> u >> v; adj[u].pb(v); adj[v].pb(u); } Pow[0] = 1; for (int i = 1; i <= n; i++) { Pow[i] = Pow[i - 1] * base; } // return cout << ok(2, 1), 0; int L = 1, R = n / 2, res = 1; while (L <= R) { int mid = (L + R) / 2; if (ok(mid, 1)) { res = 2 * mid + 1; L = mid + 1; } else R = mid - 1; } L = 1, R = n / 2; while (L <= R) { int mid = (L + R) / 2; if (ok(mid, 0)) { res = max(res, 2 * mid); L = mid + 1; } else R = mid - 1; } cout << res; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...