제출 #826028

#제출 시각아이디문제언어결과실행 시간메모리
826028KoD서열 (APIO23_sequence)C++17
11 / 100
2075 ms48384 KiB
#include "sequence.h" #include <algorithm> #include <utility> #include <vector> using std::pair; using std::vector; constexpr int inf = 1 << 30; struct segment_tree { explicit segment_tree(const vector<int>& v) { const int n = (int)v.size(); for (logn = 0; (1 << logn) < n; ++logn) ; size = 1 << logn; min.resize(2 * size); max.resize(2 * size); add.resize(size); for (int i = 0; i < n; ++i) min[i + size] = max[i + size] = v[i]; for (int i = size - 1; i > 0; --i) fetch(i); } void range_add(int l, int r, int x) { l += size, r += size; push(l), push(r); for (int s = l, t = r; s < t; s >>= 1, t >>= 1) { if (s & 1) apply(s++, x); if (t & 1) apply(--t, x); } pull(l), pull(r); } pair<int, int> fold(int l, int r) { l += size, r += size; push(l), push(r); int s = +inf, t = -inf; for (; l < r; l >>= 1, r >>= 1) { if (l & 1) { s = std::min(s, min[l]); t = std::max(t, max[l]); l += 1; } if (r & 1) { r -= 1; s = std::min(s, min[r]); t = std::max(t, max[r]); } } return {s, t}; } private: int size, logn; vector<int> min, max, add; void apply(int i, int x) { min[i] += x, max[i] += x; if (i < size) add[i] += x; } void flush(int i) { apply(2 * i + 0, add[i]); apply(2 * i + 1, add[i]); add[i] = 0; } void fetch(int i) { min[i] = std::min(min[2 * i + 0], min[2 * i + 1]); max[i] = std::max(max[2 * i + 0], max[2 * i + 1]); } void push(int i) { const int rz = __builtin_ctz(i); for (int k = logn; k > rz; --k) flush(i >> k); } void pull(int i) { i >>= __builtin_ctz(i); while (i >>= 1) fetch(i); } }; int sequence(int N, vector<int> A) { vector<vector<int>> C(N); for (int i = 0; i < N; ++i) { A[i] -= 1; C[A[i]].push_back(i); } int ret = 0; for (int i = 0, j = 0; i < N; ++i) { const int c = (int)C[i].size(); if (j <= N / 2 && N / 2 < j + c) ret = std::max(ret, c); j += c; } vector<int> initial(N + 1); for (int i = 0; i <= N; ++i) initial[i] = -i; for (int phase = 0; phase < 2; ++phase) { // segment_tree seg(initial); // for (int x = 0; x < N; ++x) { // const auto& v = C[x]; // const int n = (int)v.size(); // for (int i = 0, j = 0; i < n; i = j) { // const auto [l0, r0] = seg.fold(0, v[i] + 1); // while (j < n) { // const auto [l1, r1] = seg.fold(v[j] + 1, N + 1); // if (std::max(l0, l1) > std::min(r0, r1)) break; // j += 1; // } // ret = std::max(ret, j - i); // if (i == j) j += 1; // } // for (const int i : v) seg.range_add(i + 1, N + 1, 2); // } vector<int> a = initial; for (int x = 0; x < N; ++x) { const auto& v = C[x]; const int n = (int)v.size(); vector<int> cnt(N + 1); for (const int i : v) cnt[i + 1] += 1; for (int i = 0; i < N; ++i) cnt[i + 1] += cnt[i]; vector<int> lmin = a, rmin = a, lmax = a, rmax = a; for (int i = 0; i < N; ++i) lmin[i + 1] = std::min(lmin[i + 1], lmin[i]); for (int i = 0; i < N; ++i) lmax[i + 1] = std::max(lmax[i + 1], lmax[i]); for (int i = N - 1; i >= 0; --i) rmin[i] = std::min(rmin[i], rmin[i + 1]); for (int i = N - 1; i >= 0; --i) rmax[i] = std::max(rmax[i], rmax[i + 1]); for (int i = 0; i < N; ++i) { for (int j = i + 1; j <= N; ++j) { if (std::max(lmin[i], rmin[j]) <= std::min(lmax[i], rmax[j])) { ret = std::max(ret, cnt[j] - cnt[i]); } } } for (const int i : v) { for (int j = i + 1; j <= N; ++j) a[j] += 2; } } std::reverse(C.begin(), C.end()); } return ret; }

컴파일 시 표준 에러 (stderr) 메시지

sequence.cpp: In function 'int sequence(int, std::vector<int>)':
sequence.cpp:114:17: warning: unused variable 'n' [-Wunused-variable]
  114 |       const int n = (int)v.size();
      |                 ^
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...