Submission #535358

#TimeUsernameProblemLanguageResultExecution timeMemory
535358KoDAAQQZ (JOI15_aaqqz)C++17
100 / 100
1225 ms44920 KiB
#include <bits/stdc++.h> using std::vector; using std::array; using std::pair; using std::tuple; void setmax(int& x, const int y) { if (x < y) { x = y; } } int solve(const int N, const int C, const vector<int>& A) { vector<vector<int>> idx(C); for (int i = 0; i < N; ++i) { idx[A[i]].push_back(i); } vector<int> taken(C); const auto reset = [&](const int lowb) { for (int i = 0; i < C; ++i) { taken[i] = std::lower_bound(idx[i].begin(), idx[i].end(), lowb) - idx[i].begin(); } }; const auto empty = [&](const int x) { return taken[x] == (int)idx[x].size(); }; const auto pop = [&](const int x) { return idx[x][taken[x]++]; }; int ret = 0; vector add(N, vector<int>(N + 2)); const auto process = [&](const int left, const int right, const int except) { reset(right); vector<char> type(N); vector<pair<int, int>> consider; for (int i = left - 1, last = 0; i >= 0; --i) { if (A[i] < last or empty(A[i])) { break; } const int j = pop(A[i]); type[j] = 1; consider.emplace_back(i, j); last = A[i]; } for (int i = right; i < N; ++i) { if (type[i] == 0 and A[i] == except) { type[i] = 2; } } vector<int> bad(C + 1, N); for (int i = right; i < N; ++i) { if (type[i] == 0 and bad[A[i] + 1] == N) { bad[A[i] + 1] = i; } } for (int i = 0; i < C; ++i) { bad[i + 1] = std::min(bad[i + 1], bad[i]); } vector<int> sum(N + 1); for (int i = 0; i < N; ++i) { sum[i + 1] = sum[i] + (type[i] == 2); } vector<int> nearest(N + 1, N); for (int i = N - 1; i >= 0; --i) { nearest[i] = type[i] != 2 ? i : nearest[i + 1]; } int must = right; for (const auto& [l, r] : consider) { setmax(must, r + 1); if (bad[A[l]] < must) { break; } setmax(ret, 2 * (left - l) + sum[bad[A[l]]] - sum[right] + right - left); if (sum[must] - sum[right] + left - l == must - right) { add[l][must] += 1; add[l][nearest[must] + 1] -= 1; } } }; for (int i = 1; i < N; ++i) { process(i, i, A[i - 1]); for (int j = i; j < N; ++j) { if (A[i - 1] > A[j]) { process(i, i, A[j]); break; } } } vector make(N, vector<char>(N + 1)); for (int i = 0; i < N; ++i) { int l = i, r = i + 1; while (l > 0 and r < N and A[l - 1] == A[r]) { l -= 1; r += 1; } process(l, r, -1); make[i][i + 1] = true; } for (int i = 1; i < N; ++i) { int l = i, r = i; while (l > 0 and r < N and A[l - 1] == A[r]) { l -= 1; r += 1; } process(l, r, -1); make[i][i] = true; } for (int i = 0; i < N; ++i) { int sum = 0; for (int j = 0; j <= N; ++j) { sum += add[i][j]; make[i][j] = sum > 0; } } for (int len = 1; len < N; ++len) { for (int l = 1; l + len < N; ++l) { const int r = l + len; if (make[l][r] and A[l - 1] == A[r]) { make[l - 1][r + 1] = true; } } } for (int i = 1; i <= N; ++i) { for (int j = 0; j < i; ++j) { if (make[j][i]) { setmax(ret, i - j); } } } return ret; } int main() { int N, C; std::cin >> N >> C; vector<int> A(N), freq(C); for (auto& x : A) { std::cin >> x; x -= 1; freq[x] += 1; } int ans = *std::max_element(freq.begin(), freq.end()); setmax(ans, solve(N, C, A)); std::reverse(A.begin(), A.end()); for (auto& x : A) { x = C - x - 1; } setmax(ans, solve(N, C, A)); std::cout << ans << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...