제출 #751051

#제출 시각아이디문제언어결과실행 시간메모리
751051maeola서열 (APIO23_sequence)C++17
100 / 100
1607 ms87988 KiB
#include "sequence.h" #include <algorithm> #include <vector> using namespace std; struct Node { int sum, neg, pos; }; Node nodes[2000005]; struct Sus { int mn; bool r; }; Sus sussy[13000005]; void wind() { sussy[1].r = true; } void clean(int i) { auto &node = sussy[i]; if (node.r) { node.mn = 1e9; sussy[2 * i].r = true; sussy[2 * i + 1].r = true; node.r = false; } } void simple_upd(int i, int l, int r, int p, int x) { clean(i); auto &node = sussy[i]; if (p < l or p > r) return; if (l == r) { node.mn = min(node.mn, x); return; } int m = l + (r - l) / 2; simple_upd(2 * i, l, m, p, x); simple_upd(2 * i + 1, m + 1, r, p, x); node.mn = min(sussy[2 * i].mn, sussy[2 * i + 1].mn); } int simple_query(int i, int l, int r, int ql, int qr) { clean(i); if (qr < l or ql > r) return 1e9; if (ql <= l and qr >= r) return sussy[i].mn; // int m = (l + r) / 2; int m = l + (r - l) / 2; return min(simple_query(2 * i, l, m, ql, qr), simple_query(2 * i + 1, m + 1, r, ql, qr)); } // struct Sus // { // int mn, lazy; // bool r; // }; // // Sus sussy[8000005]; // // void wind() { // sussy[1].r = true; // } // // void clean(int i) { // auto &node = sussy[i]; // if (node.r) // { // node.mn = 1e9; // node.lazy = 1e9; // sussy[2 * i].r = true; // sussy[2 * i + 1].r = true; // node.r = false; // } // node.mn = min(node.mn, node.lazy); // sussy[2 * i].lazy = min(sussy[2 * i].lazy, node.lazy); // sussy[2 * i + 1].lazy = min(sussy[2 * i + 1].lazy, node.lazy); // } // // int set_query(int i, int l, int r, int ql, int qr, int v) { // clean(i); // auto &node = sussy[i]; // if (qr < l or ql > r) // return 1e9; // if (ql <= l and qr >= r) // { // node.lazy = min(node.lazy, v); // clean(i); // return node.mn; // } // // int m = (l + r) / 2; // int m = l + (r - l) / 2; // auto a = set_query(2 * i, l, m, ql, qr, v); // auto b = set_query(2 * i + 1, m + 1, r, ql, qr, v); // node.mn = min(sussy[2 * i].mn, sussy[2 * i + 1].mn); // return min(a, b); // } void reset() { for (auto &x : nodes) x.sum = x.neg = x.pos = 0; } Node comb(const Node &a, const Node &b) { return {a.sum + b.sum, min(a.neg, a.sum + b.neg), max(a.pos, a.sum + b.pos)}; } void upd(int i, int l, int r, int p, int x) { if (p < l or p > r) return; auto &node = nodes[i]; if (l == r) { node.sum = x; node.neg = min(x, 0); node.pos = max(x, 0); return; } int m = (l + r) / 2; upd(2 * i, l, m, p, x); upd(2 * i + 1, m + 1, r, p, x); node = comb(nodes[2 * i], nodes[2 * i + 1]); } Node query(int i, int l, int r, int ql, int qr) { if (qr < l or ql > r) return {0, 0, 0}; if (ql <= l and qr >= r) return nodes[i]; int m = (l + r) / 2; return comb(query(2 * i, l, m, ql, qr), query(2 * i + 1, m + 1, r, ql, qr)); } vector<int> possy[500005]; constexpr int L = -1e6 - 5; constexpr int R = -L; int sequence(int N, vector<int> A) { reset(); for (auto &a : possy) a.clear(); for (int i = 0; i < N; i++) { possy[A[i]].push_back(i); upd(1, 0, N - 1, i, 1); } int ans = 1; // for (int i = L; i <= R; i++) // simple_upd(1, L, R, i, 1e9, true); for (int q = 1; q <= N; q++) { auto &b = possy[q]; if (b.empty()) continue; b.push_back(N); vector<pair<int, int>> segs; int bg = 0; int ptr = 0; for (int p : b) { auto h = query(1, 0, N - 1, bg, p - 1); segs.push_back({ptr + h.neg, ptr + h.pos}); ptr += h.sum; bg = p + 1; } int m = (int)segs.size(); wind(); vector<tuple<int, int, int>> from, to; for (int i = 0; i < m; i++) { auto [a, b] = segs[i]; from.push_back({a + i, b - i, i}); to.push_back({b + i, a - i, i}); } sort(from.begin(), from.end()); sort(to.begin(), to.end()); ptr = 0; for (auto [b, a, i] : to) { while (ptr < (int)from.size() and get<0>(from[ptr]) <= b) { auto [p, q, j] = from[ptr]; simple_upd(1, L, R, q, j); ptr++; } int g = simple_query(1, L, R, a, R); ans = max(ans, i - g); } // for (auto [p, q, j] : from) // { // simple_upd(1, L, R, q, 1e9, true); // } // for (int i = 0; i < m; i++) // { // auto [a, b] = segs[i]; // int f = set_query(1, -1e6 - 5, 1e6 + 5, a - i, b + i, // i); ans = max(ans, i - f); // } // for (int i = 0; i < m; i++) // { // for (int j = i + 1; j < m; j++) // { // int d = j - i; // auto [a, b] = segs[i]; // auto [x, y] = segs[j]; // if (not (a > y + d or b < x - d)) // { // ans = max(ans, d); // } // } // } for (int p : b) upd(1, 0, N - 1, p, -1); } return ans; }
#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...