Submission #988675

#TimeUsernameProblemLanguageResultExecution timeMemory
988675maomao90Railway Trip 2 (JOI22_ho_t4)C++17
35 / 100
247 ms39836 KiB
// Hallelujah, praise the one who set me free // Hallelujah, death has lost its grip on me // You have broken every chain, There's salvation in your name // Jesus Christ, my living hope #include <bits/stdc++.h> using namespace std; #define REP(i, s, e) for (int i = (s); i < (e); i++) #define RREP(i, s, e) for (int i = (s); i >= (e); i--) template <class T> inline bool mnto(T& a, T b) {return a > b ? a = b, 1 : 0;} template <class T> inline bool mxto(T& a, T b) {return a < b ? a = b, 1: 0;} typedef long long ll; typedef long double ld; #define FI first #define SE second typedef pair<int, int> ii; typedef pair<ll, ll> pll; typedef tuple<int, int, int> iii; #define ALL(_a) _a.begin(), _a.end() #define SZ(_a) (int) _a.size() #define pb push_back typedef vector<int> vi; typedef vector<ll> vll; typedef vector<ii> vii; typedef vector<iii> viii; #ifndef DEBUG #define cerr if (0) cerr #endif const int INF = 1000000005; const ll LINF = 1000000000000000005ll; const int MAXN = 100005; const int MAXM = 200005; const int MAXL = 20; int n, k, m; ii ab[MAXM]; ii p[MAXL][MAXM]; ii src[MAXN]; int q; ii fw[MAXN]; void upd(int i, ii x) { for (; i <= n; i += i & -i) { mxto(fw[i], x); } } ii qmx(int i) { ii res = {-INF, -INF}; for (; i > 0; i -= i & -i) { mxto(res, fw[i]); } return res; } namespace DSU { int rt[MAXN], p[MAXN], rnk[MAXN]; void init() { REP (i, 1, n + 2) { p[i] = i; rt[i] = i; rnk[i] = 1; } } int findp(int i) { if (p[i] == i) { return i; } return p[i] = findp(p[i]); } bool join(int a, int b) { int pa = findp(a), pb = findp(b); if (pa == pb) { return 0; } if (rnk[pa] < rnk[pb]) { swap(pa, pb); } else if (rnk[pa] == rnk[pb]) { rnk[pa]++; } p[pb] = pa; mxto(rt[pa], rt[pb]); return 1; } } int id[MAXM]; void precomp(bool b) { iota(id, id + m, 1); sort(id, id + m, [&] (int l, int r) { return ab[l].FI > ab[r].FI; }); REP (i, 1, n + 1) { fw[i] = {-INF, 0}; } REP (_, 0, m) { int i = id[_]; if (ab[i].FI > ab[i].SE) { continue; } (b ? p[0][i].FI : p[0][i].SE) = qmx(ab[i].SE).SE; upd(ab[i].FI, {ab[i].SE, i}); } sort(id, id + m, [&] (int l, int r) { auto get = [&] (int i) { return ab[i].FI < ab[i].SE ? ab[i].FI : max(ab[i].FI - k + 1, ab[i].SE); }; return get(l) > get(r); }); REP (i, 1, n + 1) { fw[i] = {-INF, 0}; } REP (_, 0, m) { int i = id[_]; if (ab[i].FI > ab[i].SE) { upd(max(ab[i].FI - k + 1, ab[i].SE), {-ab[i].SE, i}); } else { (b ? p[0][i].SE : p[0][i].FI) = qmx(ab[i].SE).SE; } } sort(id, id + m, [&] (int l, int r) { return ab[l].SE > ab[r].SE; }); DSU::init(); REP (_, 0, m) { int i = id[_]; if (ab[i].FI > ab[i].SE) { continue; } while (DSU::rt[DSU::findp(ab[i].FI)] <= min(ab[i].SE, ab[i].FI + k - 1)) { int x = DSU::rt[DSU::findp(ab[i].FI)]; (b ? src[n - x + 1].FI : src[x].SE) = i; DSU::join(x, x + 1); } } } inline ii jump(ii x, int k) { ii res = {0, 0}; auto relax = [&] (ii y) { if (y.FI) { if (!x.FI || ab[x.FI].SE > ab[y.FI].SE) { res.FI = y.FI; } } if (y.SE) { if (!x.SE || ab[x.SE].SE < ab[y.SE].SE) { res.SE = y.SE; } } }; if (x.FI) { relax(p[k][x.FI]); } if (x.SE) { relax(p[k][x.SE]); } return res; } int main() { #ifndef DEBUG ios::sync_with_stdio(0), cin.tie(0); #endif cin >> n >> k; cin >> m; REP (i, 1, m + 1) { cin >> ab[i].FI >> ab[i].SE; } REP (b, 0, 2) { precomp(b); REP (i, 1, m + 1) { ab[i].FI = n - ab[i].FI + 1; ab[i].SE = n - ab[i].SE + 1; } } REP (k, 1, MAXL) { REP (i, 1, m + 1) { p[k][i] = jump(p[k - 1][i], k - 1); } } REP (i, 1, m + 1) { cerr << i << ": " << p[0][i].FI << ' ' << p[0][i].SE << '\n'; } REP (i, 1, n + 1) { cerr << i << ": " << src[i].FI << ' ' << src[i].SE << '\n'; } cin >> q; REP (i, 0, q) { int s, t; cin >> s >> t; ii u = src[s]; if (s < t) { if (u.SE && ab[u.SE].SE >= t) { cout << 1 << '\n'; continue; } } else { cerr << ' ' << u.FI << ' ' << ab[u.FI].SE << '\n'; if (u.FI && ab[u.FI].SE <= t) { cout << 1 << '\n'; continue; } } int res = 2; RREP (k, MAXL - 1, 0) { ii v = jump(u, k); if (s < t) { if (v.SE && ab[v.SE].SE < t) { u = v; res += 1 << k; } } else { if (v.FI && ab[v.FI].SE > t) { u = v; res += 1 << k; } } } u = jump(u, 0); if (s < t) { if (!u.SE || ab[u.SE].SE < t) { res = -1; } } else { if (!u.FI || ab[u.FI].SE > t) { res = -1; } } cout << res << '\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...