Submission #547963

#TimeUsernameProblemLanguageResultExecution timeMemory
547963JomnoiLampice (COCI19_lampice)C++17
0 / 110
5093 ms12420 KiB
#include <bits/stdc++.h> #define DEBUG 0 using namespace std; const int MAX_N = 5e4 + 10; const int P = 31; const int MOD = 1e9 + 9; char S[MAX_N]; vector <int> graph[MAX_N]; long long expo[MAX_N]; class CentroidDecomposition { private : bool ok; int max_len; long long H[MAX_N], rH[MAX_N]; int sz[MAX_N], depth[MAX_N], parent[MAX_N][20]; bitset <MAX_N> processed; vector <int> centroid, tmp; unordered_set <int> mp; public : int get_size(const int &u, const int &p) { sz[u] = 1; for(auto v : graph[u]) { if(v != p and processed[v] == false) { sz[u] += get_size(v, u); } } return sz[u]; } int get_centroid(const int &u, const int &p, const int &n) { for(auto v : graph[u]) { if(v != p and processed[v] == false and sz[v] > n / 2) { return get_centroid(v, u, n); } } return u; } void build_centroid() { queue <int> q; q.push(1); while(!q.empty()) { int u = q.front(); q.pop(); int c = get_centroid(u, -1, get_size(u, -1)); processed[c] = true; centroid.push_back(c); for(auto v : graph[c]) { if(processed[v] == false) { q.push(v); } } } } int jump(int u, const int &k) { for(int i = 0; i < 20; i++) { if(k & (1<<i)) { u = parent[u][i]; } } return u; } void preprocess(const int &u, const int &p, const int &lvl) { depth[u] = lvl; if(depth[u] > max_len) { return; } parent[u][0] = p; for(int i = 1; i < 20; i++) { parent[u][i] = parent[parent[u][i - 1]][i - 1]; } H[u] = (H[p] * P + S[u]) % MOD; rH[u] = (rH[p] + S[u] * expo[lvl]) % MOD; if(max_len == lvl + 1 and H[u] == rH[u]) { ok = true; } for(auto v : graph[u]) { if(v != p and processed[v] == false) { preprocess(v, u, lvl + 1); } } } void dfs(int u, int p) { if(depth[u] > max_len) { return; } // before substring + palindrome in current side + substring int v = jump(u, max_len - (depth[u] + 1)); if(v != 0 and H[v] == rH[v] and mp.count(((H[u] - H[parent[v][0]] * expo[max_len - depth[u] - 1]) % MOD + MOD) % MOD)) { ok = true; } tmp.push_back(H[u]); for(auto v : graph[u]) { if(v != p and processed[v] == false) { dfs(v, u); } } } bool solve(const int &len) { if(len <= 1) { return true; } max_len = len; processed = 0; ok = false; for(auto c : centroid) { processed[c] = true; H[c] = rH[c] = S[c]; // Preprocess (Some operation that process once) for(auto v : graph[c]) { if(processed[v] == false) { preprocess(v, c, 1); } } // Left to right for(auto v : graph[c]) { if(processed[v] == true) { continue; } dfs(v, c); for(auto x : tmp) { mp.insert(x); } tmp.clear(); } mp.clear(); // Right to left for(int i = graph[c].size() - 1; i >= 0; i--) { int v = graph[c][i]; if(processed[v] == true) { continue; } dfs(v, c); for(auto x : tmp) { mp.insert(x); } tmp.clear(); } mp.clear(); } return ok; } }ct; int main() { cin.tie(0)->sync_with_stdio(0); int N, l, r, mid, res, ans = 0; cin >> N >> (S + 1); for(int i = 1; i <= N - 1; i++) { int A, B; cin >> A >> B; graph[A].push_back(B); graph[B].push_back(A); } // Preprocess expo[0] = 1; for(int i = 1; i < MAX_N; i++) { expo[i] = (expo[i - 1] * P) % MOD; } for(int i = 1; i <= N; i++) { S[i] = S[i] - 'a' + 1; } ct.build_centroid(); // Compute even length l = 0, r = N / 2; while(l <= r) { mid = (l + r) / 2; if(ct.solve(2 * mid) == true) { res = mid; l = mid + 1; } else { r = mid - 1; } } ans = max(ans, 2 * res); // Compute odd length l = 0, r = N / 2; while(l <= r) { mid = (l + r) / 2; if(ct.solve(2 * mid + 1) == true) { res = mid; l = mid + 1; } else { r = mid - 1; } } ans = max(ans, 2 * res + 1); cout << ans; return 0; }

Compilation message (stderr)

lampice.cpp: In function 'int main()':
lampice.cpp:201:22: warning: 'res' may be used uninitialized in this function [-Wmaybe-uninitialized]
  201 |     ans = max(ans, 2 * 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...