This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |