Submission #676295

#TimeUsernameProblemLanguageResultExecution timeMemory
676295vuavisaoLampice (COCI19_lampice)C++14
110 / 110
4365 ms12184 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]; bool rem[N]; int cap; int pw[N], up[N], down[N]; vector<int> odd, even; int res = 1; void dfs_child(int u, int p) { ++ cnt_node; child[u] = 1; for(const auto& v : g[u]) { if(v == p || rem[v]) continue; dfs_child(v, u); child[u] += child[v]; } } int dfs_centroid(int u, int p) { for(const auto& v : g[u]) { if(v == p || rem[v]) continue; if(child[v] > cnt_node / 2) return dfs_centroid(v, u); } return u; } int get_hash(int l, int r) { if(l == 0) return down[r]; return (0ll + down[r] - 1ll * down[l - 1] * pw[r - l + 1] + 1ll * MOD * MOD) % MOD; } bool split(int u, int p) { cnt_node = 0; dfs_child(u, p); u = dfs_centroid(u, p); rem[u] = true; down[0] = up[0] = s[u] - 'a' + 1; unordered_set<int> stt = {}; function<void(int, int, int)> add = [&] (int u, int p, int len) { if(len + 1 > cap) return; down[len] = (1ll * down[len - 1] * BASE + s[u] - 'a' + 1) % MOD; stt.insert(down[len]); for(const auto& v : g[u]) { if(v == p || rem[v]) continue; add(v, u, len + 1); } }; bool have = false; function<void(int, int, int)> calc = [&] (int u, int p, int len) { if(have || len + 1 > cap) return; down[len] = (1ll * down[len - 1] * BASE + s[u] - 'a' + 1) % MOD; up[len] = (1ll * up[len - 1] + 1ll * (s[u] - 'a' + 1) * pw[len]) % MOD; if(len + 1 == cap) { if(up[len] == down[len]) { have = true; return; } } if(2 * (len + 1) > cap) { int use_palin = 2 * (len + 1) - cap - 1; if(down[use_palin] == up[use_palin]) { int hash = get_hash(use_palin, len); if(stt.find(hash) != stt.end()) { have = true; return; } } } for(const auto& v : g[u]) { if(v == p || rem[v]) continue; calc(v, u, len + 1); } }; for(const auto& v : g[u]) { if(rem[v]) continue; calc(v, u, 1); if(have) return true; add(v, u, 1); } stt.clear(); reverse(g[u].begin(), g[u].end()); for(const auto& v : g[u]) { if(rem[v]) continue; calc(v, u, 1); if(have) return true; add(v, u, 1); } for(const auto& v : g[u]) { if(rem[v]) continue; if(split(v, u)) return true; } return false; } 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; cap = s[mid]; memset(rem, false, sizeof(rem)); if(split(1, 0)) { Max_self(res, cap); l = mid + 1; } else { r = mid - 1; } } } int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); if (fopen("COCI19_lampice.inp", "r")) { freopen("COCI19_lampice.inp", "r", stdin); freopen("COCI19_lampice.out", "w", stdout); } 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

Compilation message (stderr)

lampice.cpp: In function 'int32_t main()':
lampice.cpp:140:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  140 |         freopen("COCI19_lampice.inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lampice.cpp:141:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  141 |         freopen("COCI19_lampice.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...