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;
#define f1r(i, a, b) for (int i = a; i < b; ++i)
#define f0r(i, a) f1r(i, 0, a)
#define each(t, a) for (auto& t : a)
#define mp make_pair
#define f first
#define s second
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
template <class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template <class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
template <class T> int get_pos(vector<T>& v, T x) {
return lower_bound(all(v), x) - v.begin();
}
const int INF = 1e9;
struct SegmentTree {
vpi st;
int sz;
int ty = 0;
int nil;
pi comb(pi x, pi y) {
if (ty == 0) return min(x, y);
return max(x, y);
}
void pull(int i) {
st[i] = comb(st[2 * i], st[2 * i + 1]);
}
void init(int n, int t) {
ty = t;
if (ty == 0) {
nil = INF;
} else {
nil = -INF;
}
sz = 1;
while (sz < n) sz <<= 1;
st.assign(2 * sz, mp(nil, 0));
f0r(i, sz) st[i + sz].s = i;
for (int i = sz - 1; i >= 1; i--) pull(i);
}
void upd(int p, int x, int i = 1, int l = 0, int r = -1) {
if (r == -1) r += sz;
if (p < l || r < p) return;
if (l == r) {
st[i] = comb(st[i], {x, p});
return;
}
int m = (l + r) >> 1;
upd(p, x, 2 * i, l, m);
upd(p, x, 2 * i + 1, m + 1, r);
pull(i);
}
pi query(int lo, int hi, int i = 1, int l = 0, int r = -1) {
if (r == -1) r += sz;
if (hi < l || r < lo) return {nil, nil};
else if (lo <= l && r <= hi) return st[i];
int m = (l + r) >> 1;
return comb(query(lo, hi, 2 * i, l, m), query(lo, hi, 2 * i + 1, m + 1, r));
}
};
struct IntervalUnion {
set<pi> ivals;
void insert(pi x) {
ivals.insert(x);
}
bool bad(pi x) {
auto it = ivals.lower_bound({x.f, -INF});
if (it != ivals.end()) { // first thing with left coord at least x.f
if (it->f < x.s) return true;
}
if (it == ivals.begin()) return false; // there's nothing before
it = prev(it);
if (it->s > x.f) return true;
return false;
}
};
int main() {
cin.tie(0)->sync_with_stdio(0);
int n, k; cin >> n >> k;
vpi v(n);
f0r(i, n) cin >> v[i].f >> v[i].s;
vi pts;
each(p, v) pts.pb(p.f), pts.pb(p.s);
sort(all(pts));
pts.erase(unique(all(pts)), pts.end());
each(p, v) p.f = get_pos(pts, p.f), p.s = get_pos(pts, p.s);
map<pi, int> conv; // this is not unique possibly, but that doesn't matter
f0r(i, n) conv[v[i]] = i;
vi ord(n);
iota(all(ord), 0);
sort(all(ord), [&](int x, int y) {
return v[x].f < v[y].f;
});
int d = 1;
while ((1 << d) < n) ++d;
vector<vi> L, R;
vector<vector<bool>> LB, RB; // determines whether you hit the deadend
L = R = vector<vi>(d, vi(n));
LB = RB = vector<vector<bool>>(d, vector<bool>(n));
int sz = sz(pts);
SegmentTree seg;
seg.init(sz, 0); // min segtree
for (int i = n - 1; i >= 0; i--) {
int id = ord[i];
int l = v[id].f;
int r = v[id].s;
auto res = seg.query(r, sz - 1);
if (res.f != seg.nil) {
R[0][id] = conv[{res.s, res.f}];
RB[0][id] = true;
} else {
R[0][id] = id;
}
seg.upd(l, r);
}
sort(all(ord), [&](int x, int y) {
return v[x].s < v[y].s;
});
seg.init(sz, 1);
f0r(i, n) {
int id = ord[i];
int l = v[id].f;
int r = v[id].s;
auto res = seg.query(0, l);
if (res.f != seg.nil) {
L[0][id] = conv[{res.f, res.s}];
LB[0][id] = true;
} else {
L[0][id] = id;
}
seg.upd(r, l);
}
f1r(j, 1, d) {
f0r(i, n) {
L[j][i] = L[j - 1][L[j - 1][i]];
R[j][i] = R[j - 1][R[j - 1][i]];
LB[j][i] = LB[j - 1][L[j - 1][i]] & LB[j - 1][i];
RB[j][i] = RB[j - 1][R[j - 1][i]] & RB[j - 1][i];
}
}
vi ans;
IntervalUnion IU;
auto compute = [&](int x, int y) -> int { // assumes nonoverlapping
int amt = 0;
if (x == -1 && y == -1) {
amt = 0;
} else if (x == -1) { // that means null left
int cur = y;
for (int i = d - 1; i >= 0; i--) {
if (!LB[i][cur]) continue;
cur = L[i][cur];
amt += (1 << i);
}
} else if (y == -1) {
int cur = x;
for (int i = d - 1; i >= 0; i--) {
if (!RB[i][cur]) continue;
cur = R[i][cur];
amt += (1 << i);
}
} else {
if (v[x] > v[y]) swap(x, y);
int cur = x;
for (int i = d - 1; i >= 0; i--) {
if (!RB[i][cur]) continue;
auto g = R[i][cur];
if (v[g].s <= v[y].f) {
amt += (1 << i);
cur = g;
}
}
}
return amt;
};
int cur = 0;
f0r(i, n) {
auto& p = v[i];
if (IU.bad(p)) continue;
auto it = IU.ivals.upper_bound(p);
int aft = -1;
if (it != IU.ivals.end()) aft = conv[*it];
int bef = -1;
if (it != IU.ivals.begin()) bef = conv[*prev(it)];
int now = compute(bef, aft);
int future = compute(bef, i) + compute(i, aft) + 1;
if (cur - now + future >= k) {
cur = cur - now + future;
IU.insert(p);
ans.pb(i);
}
}
if (sz(ans) >= k) {
f0r(i, k) cout << ans[i] + 1 << '\n';
} else {
cout << -1 << '\n';
}
return 0;
}
/**
* store at left coordinate right coordinate, find minimum right coordinate
*/
# | 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... |