Submission #885192

#TimeUsernameProblemLanguageResultExecution timeMemory
885192makravRailway Trip 2 (JOI22_ho_t4)C++14
100 / 100
185 ms48304 KiB
#define _USE_MATH_DEFINES #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef vector<int> vei; typedef vector<vei> vevei; #define all(a) (a).begin(), (a).end() #define sz(a) (int) a.size() #define con cout << "NO\n" #define coe cout << "YES\n"; #define str string #define pb push_back #define ff first #define sc second #define ss second #define pii pair<int, int> #define mxe max_element #define mne min_element #define stf shrink_to_fit #define f(i, l, r) for (int i = (l); i < (r); i++) #define double ld struct segtree { int n, tim; vector<pair<int, int>> t; segtree() = default; segtree(int n_) { n = n_; tim = 0; t.resize(4 * n, { 0, -1 }); } void upd(int v, int tl, int tr, int l, int r, int x) { if (l <= tl && tr <= r) { t[v] = { x, tim }; return; } if (tr <= l || tl >= r) return; int tm = (tl + tr) / 2; upd(v * 2, tl, tm, l, r, x); upd(v * 2 + 1, tm, tr, l, r, x); } pair<int, int> get(int v, int tl, int tr, int x) { if (tl + 1 == tr) { return t[v]; } int tm = (tl + tr) / 2; pair<int, int> res; if (x < tm) { res = get(v * 2, tl, tm, x); } else { res = get(v * 2 + 1, tm, tr, x); } if (res.sc > t[v].sc) return res; else return t[v]; } }; const int MAXN = 100010; vector<int> Log_2(MAXN, 0); void fill() { for (int i = 2; i < MAXN; i++) { Log_2[i] = Log_2[i / 2] + 1; } } struct SparseTableMax { int n; vector<int> a; vector<vector<int>> mx; SparseTableMax(int n_, vector<int> a_) { n = n_; a = a_; mx.resize(Log_2[n] + 1, vector<int>(n, -1)); build(); } int comp(int i, int j) { return (a[i] > a[j] ? i : j); } void build() { for (int i = n - 1; i >= 0; i--) { mx[0][i] = i; int st = 1; while ((1 << st) + i <= n) { mx[st][i] = comp(mx[st - 1][i], mx[st - 1][(1 << (st - 1)) + i]); st++; } } } int req(int l, int r) { bool sw = false; int sz = r - l + 1; int otr1 = mx[Log_2[sz]][l]; int ot2 = mx[Log_2[sz]][r - (1 << Log_2[sz]) + 1]; return comp(otr1, ot2); } }; struct SparseTableMin { int n; vector<int> a; vector<vector<int>> mx; SparseTableMin(int n_, vector<int> a_) { n = n_; a = a_; mx.resize(Log_2[n] + 1, vector<int>(n, -1)); build(); } int comp(int i, int j) { return (a[i] < a[j] ? i : j); } void build() { for (int i = n - 1; i >= 0; i--) { mx[0][i] = i; int st = 1; while ((1 << st) + i <= n) { mx[st][i] = comp(mx[st - 1][i], mx[st - 1][(1 << (st - 1)) + i]); st++; } } } int req(int l, int r) { bool sw = false; int sz = r - l + 1; int otr1 = mx[Log_2[sz]][l]; int ot2 = mx[Log_2[sz]][r - (1 << Log_2[sz]) + 1]; return comp(otr1, ot2); } }; int bfs(int n, vector<vector<int>> g, int s, int gl) { vector<int> d(n, -1); d[s] = 0; queue<int> q; q.push(s); while (!q.empty()) { auto v = q.front(); q.pop(); for (auto& u : g[v]) { if (d[u] == -1) { d[u] = d[v] + 1; q.push(u); } } } return d[gl]; } signed main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); fill(); int n, k; cin >> n >> k; int m; cin >> m; vector<pair<int, int>> a(m); f(i, 0, m) { cin >> a[i].ff >> a[i].sc; a[i].ff--; a[i].sc--; } int q; cin >> q; vector<pair<int, int>> req(q); f(i, 0, q) { cin >> req[i].ff >> req[i].sc; req[i].ff--; req[i].sc--; } vector<pair<int, int>> tor, tol; f(i, 0, m) { if (a[i].ff < a[i].sc) { tor.pb(a[i]); } else { tol.pb(a[i]); } } segtree sg(n); f(i, 0, n) { sg.upd(1, 0, n, i, i + 1, i); } sort(all(tor), [](pair<int, int> a, pair<int, int> b) { return a.sc < b.sc; }); for (int i = 0; i < sz(tor); i++) { sg.tim++; sg.upd(1, 0, n, tor[i].ff, min(tor[i].sc + 1, tor[i].ff + k), tor[i].sc); } sort(all(tol), [](pair<int, int> a, pair<int, int> b) { return a.sc < b.sc; }); segtree sg2(n); f(i, 0, n) { sg2.upd(1, 0, n, i, i + 1, i); } for (int i = sz(tol) - 1; i >= 0; i--) { sg2.tim++; sg2.upd(1, 0, n, max(tol[i].ff - k + 1, tol[i].sc), tol[i].ff + 1, tol[i].sc); } vector<pair<int, int>> seg1(n); f(i, 0, n) { seg1[i] = { sg2.get(1, 0, n, i).ff, sg.get(1, 0, n, i).ff }; } vector<int> RIGHT(n), LEFT(n); f(i, 0, n) { RIGHT[i] = seg1[i].sc; LEFT[i] = seg1[i].ff; } SparseTableMax sp(n, RIGHT); SparseTableMin sp2(n, LEFT); vector<pair<int, int>> g(n); for (int i = 0; i < n; i++) { int ir = sp.req(seg1[i].ff, seg1[i].sc); int il = sp2.req(seg1[i].ff, seg1[i].sc); g[i] = { il, ir }; } vector<vector<pair<int, int>>> up(n, vector<pair<int, int>>(19)); f(i, 0, n) up[i][0] = g[i]; auto comp_r = [&](int i, int j) { return (RIGHT[i] < RIGHT[j] ? j : i); }; auto comp_l = [&](int i, int j) { return (LEFT[i] > LEFT[j] ? j : i); }; for (int j = 1; j < 19; j++) { for (int i = 0; i < n; i++) { auto p = up[i][j - 1]; auto p2 = up[p.ff][j - 1], p3 = up[p.sc][j - 1]; int l_ind = comp_l(p2.ff, comp_l(p2.sc, comp_l(p3.ff, p3.sc))); int r_ind = comp_r(p2.ff, comp_r(p2.sc, comp_r(p3.ff, p3.sc))); up[i][j] = { l_ind, r_ind }; } } for (auto& u : req) { if (u.ff == u.sc) { cout << "0\n"; continue; } if (LEFT[u.ff] <= u.sc && u.sc <= RIGHT[u.ff]) { cout << "1\n"; continue; } auto rs = up[u.ff][18]; if (u.sc < LEFT[rs.ff] || u.sc > RIGHT[rs.sc]) { cout << "-1\n"; continue; } int ans = 0; int LF = u.ff, RG = u.ff; for (int j = 18; j >= 0; j--) { auto rs1 = up[LF][j], rs2 = up[RG][j]; int l_ind = comp_l(rs1.ff, comp_l(rs1.sc, comp_l(rs2.ff, rs2.sc))); int r_ind = comp_r(rs1.ff, comp_r(rs1.sc, comp_r(rs2.ff, rs2.sc))); if (u.sc < LEFT[l_ind] || u.sc > RIGHT[r_ind]) { LF = l_ind; RG = r_ind; ans += (1 << j); } } assert(ans + 2 <= n); cout << ans + 2 << '\n'; } return 0; }

Compilation message (stderr)

Main.cpp: In member function 'int SparseTableMax::req(int, int)':
Main.cpp:103:14: warning: unused variable 'sw' [-Wunused-variable]
  103 |         bool sw = false;
      |              ^~
Main.cpp: In member function 'int SparseTableMin::req(int, int)':
Main.cpp:139:14: warning: unused variable 'sw' [-Wunused-variable]
  139 |         bool sw = false;
      |              ^~
#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...