Submission #648470

#TimeUsernameProblemLanguageResultExecution timeMemory
648470lto5Lampice (COCI19_lampice)C++14
17 / 110
5032 ms10192 KiB
#include <bits/stdc++.h> using namespace std; #define db(x) cerr << #x << " = " << x << endl const int N = 50005; const int BASE = 311; int n; string s; vector <int> g[N]; long long power[N]; int par[N]; int child[N]; int down[N]; bool deleted[N]; int h[N]; long long hash_s[N]; long long rev_hash[N]; vector <int> path; vector <int> vertices; multiset <long long> mp; int ans = 0; int need; int rt_cen; void pre() { power[0] = 1; for (int i = 1; i < N; i++) { power[i] = power[i - 1] * BASE; } } void read() { cin >> n >> s; s = ' ' + s; for (int i = 2; i <= n; i++) { int u, v; cin >> u >> v; g[u].emplace_back(v); g[v].emplace_back(u); } } void dfs_child (int u, int par = -1) { vertices.push_back(u); child[u] = 1; for (int v : g[u]) { if (v == par || deleted[v]) continue; dfs_child(v, u); child[u] += child[v]; } } int find_centroid (int u, int n, int par = -1) { for (int v : g[u]) { if (v == par || deleted[v]) continue; if (child[v] * 2 > n) return find_centroid(v, n, u); } return u; } void dfs_add (int u, int delta) { h[u] = h[par[u]] + 1; hash_s[u] = hash_s[par[u]] * BASE + s[u]; rev_hash[u] = rev_hash[par[u]] + s[u] * power[h[par[u]]]; if (delta > 0) mp.insert(hash_s[u]); else mp.erase(mp.find(hash_s[u])); for (int v : g[u]) { if (v == par[u] || deleted[v]) continue; par[v] = u; dfs_add(v, delta); } } bool dfs_calc (int u) { path.push_back(u); if (h[u] == need && hash_s[u] == rev_hash[u]) { return true; } int rem = need - h[u]; if (rem == 0) { if (hash_s[u] == rev_hash[u]) { return true; } } else if (rem > 0) { int pos = (int)path.size() - rem - 1; if (pos >= 0) { int p = path[pos]; long long need_hash = hash_s[u] - hash_s[par[p]] * power[h[u] - h[p] + 1]; if (hash_s[p] == rev_hash[p] && mp.count(need_hash)) { return true; } } } for (int v : g[u]) { if (v == par[u] || deleted[v]) continue; par[v] = u; if (dfs_calc(v)) return true; } path.pop_back(); return false; } void init() { for (int u = 1; u <= n; u++) { hash_s[u] = 0; par[u] = 0; deleted[u] = 0; child[u] = 0; rev_hash[u] = 0; h[u] = 0; } mp.clear(); path.clear(); } void reset() { for (int v : vertices) { hash_s[v] = 0; par[v] = 0; child[v] = 0; rev_hash[v] = 0; h[v] = 0; } vertices.clear(); } bool centroid (int u) { vertices.clear(); dfs_child(u); u = find_centroid(u, child[u]); rt_cen = u; reset(); h[u] = 1; hash_s[u] = s[u]; rev_hash[u] = s[u]; deleted[u] = true; path.clear(); mp.clear(); path.push_back(u); for (int v : g[u]) { if (deleted[v]) continue; par[v] = u; dfs_add(v, 1); } for (int v : g[u]) { if (deleted[v]) continue; dfs_add(v, -1); if (dfs_calc(v)) return true; dfs_add(v, 1); } for (int v : g[u]) if (!deleted[v] && centroid(v)) return true; return false; } bool check (int len) { if (len > n) return false; init(); if (len == 1) return true; need = len; return centroid(1); } void bs (int delta) { int L = 0, R = (n + 1) / 2; while (L <= R) { int mid = (L + R) / 2; if (check(2 * mid + delta)) ans = max(ans, 2 * mid + delta), L = mid + 1; else R = mid - 1; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); // freopen("input.txt", "r", stdin); pre(); read(); if (n == 1) { cout << 1; return 0; } if (n == 2) { cout << (s[1] == s[2] ? 2 : 1); return 0; } bs(0); bs(1); cout << ans; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...