Submission #685731

#TimeUsernameProblemLanguageResultExecution timeMemory
685731JohannTeams (CEOI11_tea)C++14
70 / 100
2563 ms35320 KiB
#include "bits/stdc++.h" using namespace std; typedef pair<int, int> pii; typedef vector<pii> vpii; typedef vector<int> vi; typedef vector<vi> vvi; #define all(x) (x).begin(), (x).end() #define sz(x) (int)(x).size() struct segtree { int size; vpii arr; void init(int n) { ++n; size = 1; while (size < n) size *= 2; arr.assign(2 * size, {INT_MIN, -1}); for (int i = size; i < 2 * size; ++i) arr[i] = {INT_MIN, i - size}; for (int i = size - 1; i > 0; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]); set(0, 0); } void set(int i, int v) { set(i, v, 1, 0, size); } void set(int i, int v, int x, int lx, int rx) { if (rx - lx == 1) { arr[x] = {v, i}; return; } int m = (lx + rx) / 2; if (i < m) set(i, v, 2 * x, lx, m); else set(i, v, 2 * x + 1, m, rx); arr[x] = max(arr[2 * x], arr[2 * x + 1]); } pii query(int l, int r) { return query(max(l, 0), max(r, 0), 1, 0, size); } pii query(int l, int r, int x, int lx, int rx) { if (l <= lx && rx <= r) return arr[x]; if (l >= rx || lx >= r) return {INT_MIN, -1}; int m = (lx + rx) / 2; return max(query(l, r, 2 * x, lx, m), query(l, r, 2 * x + 1, m, rx)); } void print(int n) { for (int i = size; i < min(size + n, 2 * size); ++i) cout << arr[i].first << " "; cout << "\n"; } }; segtree seg; vi konstruct(vpii &A, int limit) { int n = sz(A); seg.init(n); vi last(n, -1); for (int i = 0; i < n; ++i) { pii tmp; if (i + 1 >= A[i].first) tmp = seg.query(i + 1 - limit, i + 2 - A[i].first); else tmp = {INT_MIN, -1}; last[i] = (tmp.first < 0) ? -1 : tmp.second - 1; seg.set(i + 1, tmp.first + 1); // seg.print(n + 1); } vi ans; int idx = n - 1; while (idx > -1) { ans.push_back(idx); idx = last[idx]; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vpii A(n); for (int i = 0; i < n; ++i) cin >> A[i].first, A[i].second = i + 1; sort(all(A)); int opt = sz(konstruct(A, n)); int l = A.back().first, r = n; while (l < r) { int m = (l + r) / 2; int ans = sz(konstruct(A, m)); if (ans < opt) l = m + 1; else r = m; } vi order = konstruct(A, l); reverse(all(order)); cout << sz(order) << "\n"; int idx = 0; for (int x : order) { cout << x - idx + 1 << " "; while (idx <= x) cout << A[idx++].second << " "; cout << "\n"; } cout << "\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...
#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...