Submission #838755

#TimeUsernameProblemLanguageResultExecution timeMemory
838755popovicirobertPalindromes (APIO14_palindrome)C++14
23 / 100
164 ms44148 KiB
#include <bits/stdc++.h> using namespace std; using ull = unsigned long long; constexpr int BASE = (int) 1e9 + 7; constexpr int MAXN = (int) 3e5; char s[MAXN + 5]; ull pref_hash[MAXN + 5]; ull power[MAXN + 5]; inline ull Get(int l, int r) { return pref_hash[r] - pref_hash[l - 1] * power[r - l + 1]; } char str[2 * MAXN + 5]; int len[2 * MAXN + 5]; int Build(char* s, int n) { power[0] = 1; for (int i = 1; i <= n; i++) { pref_hash[i] = pref_hash[i - 1] * BASE + s[i] - 'a' + 1; power[i] = power[i - 1] * BASE; } int size = 0; str[++size] = '*'; for (int i = 1; i <= n; i++) { str[++size] = s[i]; str[++size] = '*'; } return size; } void Manacher(char* str, int size) { int pos = 1; len[1] = 1; for (int i = 2; i <= size; i++) { len[i] = 1; if (pos + len[pos] >= i) { len[i] = min(pos + len[pos] - i, len[2 * pos - i]); } while (i - len[i] >= 1 && i + len[i] <= size && str[i - len[i]] == str[i + len[i]]) { len[i]++; } if (pos + len[pos] < i + len[i]) { pos = i; } } } unordered_map<ull, int> nodeId; vector<vector<int>> g; vector<int> nodeFreq(1); vector<int> nodeLen(1); void BuildGraph(int size) { int ID = 0; for (int i = 1; i <= size; i++) { int l = len[i]; if (i % 2 == l % 2) { l--; } int prevId = 0; while (l > 0) { ull currHash; int mid = i / 2; if (i % 2 == 1) { currHash = Get(mid - l / 2 + 1, mid + l / 2); } else { currHash = Get(mid - l / 2, mid + l / 2); } int& currId = nodeId[currHash]; if (currId == 0) { currId = ++ID; nodeLen.push_back(l); nodeFreq.push_back(0); } if (currId >= (int)g.size()) { g.resize(currId + 1); } if (prevId == 0) { nodeFreq[currId]++; } else { g[prevId].push_back(currId); } if (currId != ID) { break; } prevId = currId; l -= 2; } } } int main() { #ifdef HOME ifstream cin("input.in"); ofstream cout("output.out"); #endif ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); cin >> (s + 1); int n = strlen(s + 1); int size = Build(s, n); Manacher(str, size); // for (int i = 1; i <= size; i++) { // cerr << (char)str[i] << " "; // } // cerr << "\n"; // for (int i = 1; i <= size; i++) { // cerr << len[i] << " "; // } // cerr << "\n"; BuildGraph(size); int nodes = (int)g.size() - 1; vector<int> order(nodes); iota(order.begin(), order.end(), 1); sort(order.begin(), order.end(), [](const int& a, const int& b) { return nodeLen[a] > nodeLen[b]; }); long long answer = 0; for (auto node : order) { // cerr << nodeFreq[node] << " " << nodeLen[node] << "\n"; answer = max(answer, 1LL * nodeFreq[node] * nodeLen[node]); for (auto son : g[node]) { nodeFreq[son] += nodeFreq[node]; } } cout << answer; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...