Submission #674140

#TimeUsernameProblemLanguageResultExecution timeMemory
674140vuavisaoLampice (COCI19_lampice)C++14
17 / 110
5084 ms8296 KiB
#include<bits/stdc++.h> #pragma GCC optimize("O3") #pragma GCC optimize("unroll-loops") #define ll long long using namespace std; template<typename Lhs, typename Rhs> inline void Max_self(Lhs &a, Rhs b) { a = (a > b ? a : b); } template<typename Lhs, typename Rhs> inline void Min_self(Lhs &a, Rhs b) { a = (a < b ? a : b); } const int N = 5e4 + 10; const int MOD = 1e9 + 7; const int BASE = 128; int n; string s; vector<int> g[N]; int cnt_node, child[N]; int parent[N]; int limit; int pw[N], up[N], down[N]; unordered_map<int, int> mpp; vector<int> odd, even; int res = 1; void dfs_child(int u, int p); void dfs_child(int u, int p) { ++ cnt_node; child[u] = 1; for(const auto& v : g[u]) { if(v == p || parent[v]) continue; dfs_child(v, u); child[u] += child[v]; } } int dfs_centroid(int u, int p); int dfs_centroid(int u, int p) { for(const auto& v : g[u]) { if(v == p || parent[v]) continue; if(child[v] > cnt_node / 2) return dfs_centroid(v, u); } return u; } /// 0 : add question /// 1 : query question bool dfs_calc(int u, int p, int len, int type); bool dfs_calc(int u, int p, int len, int type) { if(len + 1 > limit) return false; auto get_hash = [&] (int l, int r) -> ll { if(l == 0) return down[r]; return (1ll * down[r] - 1ll * down[l - 1] * pw[r - l + 1] % MOD + MOD) % MOD; }; down[len] = (1ll * down[len - 1] * BASE + s[u]) % MOD; up[len] = (1ll * up[len - 1] + 1ll * s[u] * pw[len]) % MOD; if(type == 0) { ++ mpp[down[len]]; } else { if(len + 1 == limit) { if(up[len] == down[len]) return true; } else { if(2 * (len + 1) > limit) { ll use_palin = 2 * (len + 1) - limit - 1; if(down[use_palin] == up[use_palin]) { int hash = get_hash(use_palin, len); if(mpp.find(hash) != mpp.end()) return true; } } } } for(const auto& v : g[u]) { if(v == p || parent[v]) continue; if(dfs_calc(v, u, len + 1, type)) return true; } return false; } bool split(int u, int p); bool split(int u, int p) { cnt_node = 0; dfs_child(u, p); int centroid = dfs_centroid(u, p); if(p == 0) { p = centroid; } parent[centroid] = p; down[0] = up[0] = s[centroid]; for(const auto& v : g[centroid]) { if(parent[v]) continue; if(dfs_calc(v, centroid, 1, 1)) return true; dfs_calc(v, centroid, 1, 0); } mpp.clear(); reverse(g[centroid].begin(), g[centroid].end()); for(const auto& v : g[centroid]) { if(parent[v]) continue; if(dfs_calc(v, centroid, 1, 1)) return true; dfs_calc(v, centroid, 1, 0); } mpp.clear(); for(const auto& v : g[centroid]) { if(parent[v]) continue; if(split(v, centroid)) return true; } return false; } void solve(bool ODD); void solve(bool ODD) { const auto& s = (ODD ? odd : even); int l = 0, r = (int) s.size() - 1; while(l <= r) { int mid = (l + r) >> 1; mpp.clear(); for(int i = 0; i <= n; ++ i) { parent[i] = 0; } limit = s[mid]; if(split(1, 0)) { Max_self(res, limit); l = mid + 1; } else { r = mid - 1; } } } int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n >> s; s = ' ' + s; for(int i = 2; i <= n; ++ i) { int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } pw[0] = 1; for(int i = 1; i <= n; ++ i) { pw[i] = 1ll * pw[i - 1] * BASE % MOD; if(i & 1) { if(i > 1) { odd.push_back(i); } } else { even.push_back(i); } } solve(0); solve(1); cout << res; return 0; } /// Code by vuavisao
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...