#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define int long long
#define pb push_back
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define f(a) for(int i = 0; i<a; ++i)
#define deb(a) cerr<<a<<endl;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef string str;
typedef vector<str> vestr;
typedef vector<int> vei;
typedef vector<vector<int>> veve;
struct SparseTable {
vector<pair<int, int>> a;
vector<vector<int>> spmin, spmax;
SparseTable() {}
void build(vector<pair<int, int>> c) {
a = c;
int n = a.size();
int log2n = log2(n) + 1;
spmin.resize(log2n, vector<int>(n));
for (int i = 0; i < n; ++i) spmin[0][i] = i;
for (int i = 1; i < log2n; ++i) {
for (int j = 0; j < n; ++j) {
int t = min(j + (1<<(i-1)), n - 1);
if (a[spmin[i - 1][j]] < a[spmin[i - 1][t]]) spmin[i][j] = spmin[i - 1][j];
else spmin[i][j] = spmin[i - 1][t];
}
}
spmax.resize(log2n, vector<int>(n));
for (int i = 0; i < n; ++i) spmax[0][i] = i;
for (int i = 1; i < log2n; ++i) {
for (int j = 0; j < n; ++j) {
int t = min(j + (1<<(i-1)), n - 1);
if (a[spmax[i - 1][j]] > a[spmax[i - 1][t]]) spmax[i][j] = spmax[i - 1][j];
else spmax[i][j] = spmax[i - 1][t];
}
}
}
int min_ind(int l, int r) {
int lg2 = log2(r - l + 1);
r++;
if (a[spmin[lg2][l]] < a[spmin[lg2][r - (1<<lg2)]]) return spmin[lg2][l];
return spmin[lg2][r - (1<<lg2)];
}
pair<int, int> get_min(int l, int r) {
int lg2 = log2(r - l + 1);
r++;
if (a[spmin[lg2][l]] < a[spmin[lg2][r - (1<<lg2)]]) return a[spmin[lg2][l]];
return a[spmin[lg2][r - (1<<lg2)]];
}
int max_ind(int l, int r) {
int lg2 = log2(r - l + 1);
r++;
if (a[spmax[lg2][l]] > a[spmax[lg2][r - (1<<lg2)]]) return spmax[lg2][l];
return spmax[lg2][r - (1<<lg2)];
}
pair<int, int> get_max(int l, int r) {
int lg2 = log2(r - l + 1);
r++;
if (a[spmax[lg2][l]] > a[spmax[lg2][r - (1<<lg2)]]) return a[spmax[lg2][l]];
return a[spmax[lg2][r - (1<<lg2)]];
}
};
const int INF = 1e8;
struct Node {
pair<int, int> mx;
};
struct SegmentTree {
vector<Node> tr;
int sz;
SegmentTree(vector<int> a) {
int n = a.size();
sz = (1ll<<(int)(log2(n)))*2;
tr.resize(2*sz);
for (int i = 0; i < 2 * sz; ++i) tr[i] = {{-INF, -INF}};
for (int i = 0; i < n; ++i) {
tr[i + sz - 1] = {{a[i], i}};
}
for (int i = sz - 2; i >= 0; --i) tr[i] = merge(tr[2 * i + 1], tr[2 * i + 2]);
}
Node merge(Node a, Node b) {
return {max(a.mx, b.mx)};
}
Node get(int v, int l, int r, int ql, int qr) {
if(ql <= l && qr >= r) {
return tr[v];
}
if(l >= qr || r <= ql) return {{-INF, -INF}};
int m = (l + r) / 2;
return merge(get(2 * v + 1, l, m, ql, qr), get(2 * v + 2, m, r, ql, qr));
};
Node get(int ql, int qr) {
return get(0, 0, sz, ql, qr);
}
void update(int v, int l, int r, int ind, pair<int, int> x) {
if(l > ind || r <= ind) return;
if(r == l + 1) {
tr[v].mx = x;
return;
}
int m = (l + r) / 2;
update(2*v+1, l, m, ind, x);
update(2*v+2, m, r, ind, x);
tr[v].mx = max(tr[2*v+1].mx, tr[2*v+2].mx);
}
void update(int ind) {
pair<int, int> x = {-INF, -INF};
update(0, 0, sz, ind, x);
}
};
struct SegmentTree2 {
vector<Node> tr;
int sz;
SegmentTree2(vector<int> a) {
int n = a.size();
sz = (1ll<<(int)(log2(n)))*2;
tr.resize(2*sz);
for (int i = 0; i < 2 * sz; ++i) tr[i] = {{INF, INF}};
for (int i = 0; i < n; ++i) {
tr[i + sz - 1] = {{a[i], i}};
}
for (int i = sz - 2; i >= 0; --i) tr[i] = merge(tr[2 * i + 1], tr[2 * i + 2]);
}
Node merge(Node a, Node b) {
return {min(a.mx, b.mx)};
}
Node get(int v, int l, int r, int ql, int qr) {
if(ql <= l && qr >= r) {
return tr[v];
}
if(l >= qr || r <= ql) return {{INF, INF}};
int m = (l + r) / 2;
return merge(get(2 * v + 1, l, m, ql, qr), get(2 * v + 2, m, r, ql, qr));
};
Node get(int ql, int qr) {
return get(0, 0, sz, ql, qr);
}
void update(int v, int l, int r, int ind, pair<int, int> x) {
if(l > ind || r <= ind) return;
if(r == l + 1) {
tr[v].mx = x;
return;
}
int m = (l + r) / 2;
update(2*v+1, l, m, ind, x);
update(2*v+2, m, r, ind, x);
tr[v].mx = min(tr[2*v+1].mx, tr[2*v+2].mx);
}
void update(int ind) {
pair<int, int> x = {INF, INF};
update(0, 0, sz, ind, x);
}
};
void solve() {
int n;
cin >> n;
vector<int> l(n), r(n);
f(n) {
cin >> l[i] >> r[i];
l[i]--;
r[i]--;
}
// if (n > 2500) {
// int q, k;
// cin >> q >> k;
// int ans = 1, R = r[0], R2 = 0;
// while (R != n - 1) {
// int tt = 0;
// for (int i = R2 + 1; i <= R; ++i) {
// tt = max(tt, r[i]);
// }
// if (tt <= R) {
// ans = -1;
// break;
// }
// ans++;
// R2 = R;
// R = tt;
// }
// cout << ans << '\n';
// return;
// }
set<pair<pair<int, int>, int>> ord; // {{dp[i], r[i]}, i}
// for (auto e : ord) cout << e << ' '; cout << '\n';
vector<bool> used(n);
vector<pair<int, int>> dp1(n, {1e8, 1e8});
SegmentTree cur(r);
SegmentTree2 cur2(l);
f(n) if (l[i] == 0) ord.insert({{1, -r[i]}, i});
f(n) if (l[i] == 0) used[i] = 1;
f(n) if (l[i] == 0) dp1[i].first = 1;
f(n) if (l[i] == 0) dp1[i].second = -r[i];
f(n) if (l[i] == 0) cur.update(i);
f(n) if (l[i] == 0) cur2.update(i);
while(ord.size()) {
int i = (*ord.begin()).second;
// cout << i << ' ';
dp1[i].second = min(dp1[i].second, -r[i]);
while(1) {
pair<int, int> au = cur.get(0, i).mx;
// cout << au.second << endl;
if (au.first < i) break;
swap(au.first, au.second);
dp1[au.first] = {dp1[i].first + 1, dp1[i].second};
dp1[au.first].second = min(dp1[au.first].second, -r[au.first]);
ord.insert({dp1[au.first], au.first});
cur.update(au.first);
cur2.update(au.first);
}
while(1) {
pair<int, int> au = cur2.get(i, n).mx;
if (au.first > i) break;
swap(au.first, au.second);
dp1[au.first] = {dp1[i].first + 1, dp1[i].second};
dp1[au.first].second = min(dp1[au.first].second, -r[au.first]);
ord.insert({dp1[au.first], au.first});
cur.update(au.first);
cur2.update(au.first);
}
// cout << endl;
ord.erase(ord.begin());
}
// for (auto e : dp1) cout << e.first << ' '; cout << '\n';
// for (auto e : ord) cout << e << ' '; cout << '\n';
vector<pair<int, int>> dp2(n, {1e8, 1e8});
SegmentTree cur3(r);
SegmentTree2 cur4(l);
used.clear();
used.resize(n);
f(n) if (r[i] == n - 1) ord.insert({{1, l[i]}, i});
f(n) if (r[i] == n - 1) used[i] = 1;
f(n) if (r[i] == n - 1) dp2[i].first = 1;
f(n) if (r[i] == n - 1) dp2[i].second = l[i];
f(n) if (r[i] == n - 1) cur3.update(i);
f(n) if (r[i] == n - 1) cur4.update(i);
while(ord.size()) {
int i = (*ord.begin()).second;
dp2[i].second = min(dp2[i].second, l[i]);
while(1) {
pair<int, int> au = cur3.get(0, i).mx;
if (au.first < i) break;
swap(au.first, au.second);
dp2[au.first] = {dp2[i].first + 1, dp2[i].second};
dp2[au.first].second = min(dp2[au.first].second, l[au.first]);
ord.insert({dp2[au.first], au.first});
cur3.update(au.first);
cur4.update(au.first);
}
while(1) {
pair<int, int> au = cur4.get(i, n).mx;
// cout << "WOW" << au.first << endl;
if (au.first > i) break;
swap(au.first, au.second);
dp2[au.first] = {dp2[i].first + 1, dp2[i].second};
dp2[au.first].second = min(dp2[au.first].second, l[au.first]);
ord.insert({dp2[au.first], au.first});
cur3.update(au.first);
cur4.update(au.first);
}
ord.erase(ord.begin());
}
// for (auto e : dp1) cout << e.first << ' '; cout << '\n';
int q;
cin >> q;
SparseTable fdp1, fdp2;
fdp1.build(dp1);
fdp2.build(dp2);
for (int i = 0; i < q; ++i) {
int x;
cin >> x;
--x;
if (dp1[x].first > 2 * n || dp2[x].first > 2 * n) {
cout << "-1\n";
continue;
}
int ans = dp1[x].first;
if (dp1[x].second != -(n - 1)) ans += fdp2.get_min(0, -dp1[x].second).first;
int ans2 = dp2[x].first;
if (dp2[x].second != 0) ans2 += fdp1.get_min(dp2[x].second, n - 1).first;
cout << min(ans, ans2) << '\n';
}
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
int tc = 1;
// cin >> tc;
for (int t = 1; t <= tc; t++) {
// cout << "Case #" << t << ": ";
solve();
}
}
# | 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... |