Submission #530460

#TimeUsernameProblemLanguageResultExecution timeMemory
530460mat50013Lampice (COCI19_lampice)C++11
0 / 110
5068 ms9056 KiB
#include <bits/stdc++.h> #define d 256 #define MOD 1000000007 using namespace std; /* Avem un arbore cu n noduri, fiecare nod initial are o culoare. Numim segment palindromic [u, v] daca lantul parcus de la u->v e acelasi cu cel parcus de la v->u Trebuie sa gasim cel mai lung segment palindromic. */ const int NMAX(50005); using ll = long long; ll putH[NMAX], h[NMAX]; int cul[NMAX], dist[NMAX], dp[NMAX][18], dad[NMAX]; vector<int> G[NMAX]; bool viz[NMAX]; inline void precalc(int nod) { for(int pt = 1; pt <= 17; ++pt) if(dp[nod][pt - 1] != -1) dp[nod][pt] = dp[dp[nod][pt - 1]][pt - 1]; viz[nod] = 1; for(auto it: G[nod]) if(!viz[it]) { dad[it] = nod; dp[it][0] = nod; h[it] = (h[nod] * d + cul[it]) % MOD; dist[it] = dist[nod] + 1; precalc(it); } } inline int LCA(int x, int y) { if(dist[x] < dist[y]) swap(x, y); for(int pt = 17; pt >= 0; --pt) if(dist[x] - (1 << pt) >= dist[y]) x = dp[x][pt]; if(x == y) return x; for(int pt = 17; pt >= 0; -- pt) if(dp[x][pt] != -1 && dp[y][pt] != -1 && dp[x][pt] != dp[y][pt]) x = dp[x][pt], y = dp[y][pt]; return dp[x][0]; } inline int getD(int x, int dist) { for(int pt = 17; pt >= 0; --pt) if(dist - (1 << pt) >= 0) x = dp[x][pt], dist -= (1 << pt); return x; } int main() { ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0); int n; string s; cin >> n >> s; for(int i = 0; i < n; ++i) cul[i + 1] = s[i]; for(int i = 1; i < n; ++i) { int x, y; cin >> x >> y; G[x].push_back(y); G[y].push_back(x); } for(int i = 1; i <= n; ++i) for(int pt = 0; pt <= 17; ++pt) dp[i][pt] = -1; dp[1][0] = 0; h[1] = cul[1]; precalc(1); putH[0] = 1; for(int p = 1; p <= n; ++p) putH[p] = putH[p] * d % MOD; int maxx = 0; for(int nodS = 1; nodS <= n; ++nodS) for(int nodD = nodS + 1; nodD <= n; ++nodD) { int lc = LCA(nodS, nodD); if(nodS != lc && nodD != lc) { int st = nodS, dr = nodD; if(dist[st] > dist[dr]) swap(st, dr); ll h1 = (h[st] - h[dad[lc]] * putH[dist[dad[lc]]] % MOD + MOD) % MOD; int care = getD(dr, dist[st] - dist[lc] + 1); ll h2 = (h[dr] - h[care] * putH[dist[care]] % MOD + MOD) % MOD; //cerr << h1 << ' ' << h2 << '\n'; if(h1 == h2) { int i = getD(nodD, dist[nodD] - dist[lc] - 1); int j = dad[care]; bool ok = 1; while(dist[i] < dist[j]) { if(cul[i] != cul[j]) { ok = 0; break; } ++i, --j; } if(ok) maxx = max(maxx, dist[nodS] - dist[lc] + dist[nodD] - dist[lc] + 1); } } else { int st = nodS, dr = nodD; if(dist[st] > dist[dr]) swap(st, dr); bool ok = 1; while(dist[st] < dist[dr]) { if(cul[st] != cul[dr]) { ok = 0; break; } ++st, --dr; } if(ok) maxx = max(maxx, abs(dist[nodD] - dist[nodS]) + 1); } } cout << maxx << '\n'; 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...