Submission #106936

#TimeUsernameProblemLanguageResultExecution timeMemory
106936FlappyFishGolf (JOI17_golf)C++14
100 / 100
5937 ms494680 KiB
#include <bits/stdc++.h> using namespace std; const int U_MAX = 45678999; const int MAX = 262144; int sum[U_MAX], left_son[U_MAX], right_son[U_MAX]; struct event { int x, y, type; event(int a, int b, int t): x(a), y(b), type(t) { } bool operator <(const event &a) const { if (x != a.x) { return x < a.x; } else if (type != a.type) { return type < a.type; } else { return y < a.y; } } }; struct range { int x, L, R; range(int a, int l, int r): x(a), L(l), R(r) { } }; int main() { do { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); } while (false); int n, sx, sy, tx, ty; cin >> sx >> sy >> tx >> ty; cin >> n; vector<int> vec_x, vec_y; auto add_point = [&] (int x, int y) { vec_x.push_back(x); vec_y.push_back(y); }; add_point(sx, sy); add_point(tx, ty); vector<int> xl(n), yl(n), xr(n), yr(n); for (int i = 0; i < n; i++) { cin >> xl[i] >> xr[i] >> yl[i] >> yr[i]; add_point(xl[i], yl[i]); add_point(xr[i], yr[i]); } auto normalize = [&] (vector<int> &vec) { sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()), vec.end()); }; normalize(vec_x); normalize(vec_y); auto get_idx_x = [&] (int &x) { x = lower_bound(vec_x.begin(), vec_x.end(), x) - vec_x.begin() + 1; }; auto get_idx_y = [&] (int &y) { y = lower_bound(vec_y.begin(), vec_y.end(), y) - vec_y.begin() + 1; }; get_idx_x(sx); get_idx_y(sy); get_idx_x(tx); get_idx_y(ty); for (int i = 0; i < n; i++) { get_idx_x(xl[i]); get_idx_y(yl[i]); get_idx_x(xr[i]); get_idx_y(yr[i]); } int node_cnt = 0; function<int (int &, int, int, int, int)> add_in = [&] (int &u, int l, int r, int qx, int qy) { if (!u) { node_cnt++; u = node_cnt; } if (l == r) { if (sum[u]) { return 0; } else { sum[u] = qy + 1; return 1; } } else { int mid = (l + r) / 2, result = 0; if (qx <= mid) { result = add_in(left_son[u], l, mid, qx, qy); } else { result = add_in(right_son[u], mid + 1, r, qx, qy); } sum[u] += result; return result; } }; function<void (vector<int> &, int, int, int, int, int, int, int)> add_out = [&] (vector<int> &root, int u, int l, int r, int ql, int qr, int qx, int qy) { if (l == ql && r == qr) { add_in(root[u], 0, MAX - 1, qx, qy); } else { int mid = (l + r) / 2, x = u + 1, y = u + (mid - l + 1) * 2; if (qr <= mid) { add_out(root, x, l, mid, ql, qr, qx, qy); } else if (ql > mid) { add_out(root, y, mid + 1, r, ql, qr, qx, qy); } else { add_out(root, x, l, mid, ql, mid, qx, qy); add_out(root, y, mid + 1, r, mid + 1, qr, qx, qy); } } }; auto init = [&] (vector<int> &root) { vector<event> eve; eve.emplace_back(sx, sy, 0); eve.emplace_back(tx, ty, 0); for (int i = 0; i < n; i++) { eve.emplace_back(xl[i], yl[i], 1); eve.emplace_back(xl[i], yr[i], 1); eve.emplace_back(xr[i], yl[i], -1); eve.emplace_back(xr[i], yr[i], -1); eve.emplace_back(xl[i], yl[i], 0); eve.emplace_back(xr[i], yl[i], 0); } sort(eve.begin(), eve.end()); set<int> important; important.insert(0); important.insert(MAX - 1); vector<range> result; for (auto e : eve) { int x = e.x, y = e.y, type = e.type; if (type == 1) { important.insert(y); } else if (type == -1) { important.erase(y); } else { auto it = important.upper_bound(y); int R = *it, L = *--it; add_out(root, 0, 0, MAX - 1, L, R, x, result.size()); result.emplace_back(x, L, R); } } return result; }; auto reverse_xy = [&] () { swap(sx, sy); swap(tx, ty); swap(xl, yl); swap(xr, yr); }; vector<int> root_x(MAX * 2), root_y(MAX * 2); auto range_x = init(root_x); reverse_xy(); auto range_y = init(root_y); reverse_xy(); vector<int> dis_x(range_x.size(), INT_MAX), dis_y(range_y.size(), INT_MAX); queue<pair<int, int> > que; for (int i = 0; i < range_x.size(); i++) { if (range_x[i].x == sx && sy >= range_x[i].L && sy <= range_x[i].R) { dis_x[i] = 1; que.emplace(i, 0); } } for (int i = 0; i < range_y.size(); i++) { if (range_y[i].x == sy && sx >= range_y[i].L && sx <= range_y[i].R) { dis_y[i] = 1; que.emplace(i, 1); } } function<int (int, int, int, int, int, int, int)> fast_in = [&] (int u, int l, int r, int ql, int qr, int qv, int xy) { if (!u || !sum[u]) { return 0; } else if (l == r) { int v = sum[u] - 1; auto &dis = xy ? dis_x : dis_y; if (dis[v] == INT_MAX) { dis[v] = qv; que.emplace(v, !xy); } sum[u] = 0; return 1; } else { int mid = (l + r) / 2, result = 0; if (qr <= mid) { result += fast_in(left_son[u], l, mid, ql, qr, qv, xy); } else if (mid < ql) { result += fast_in(right_son[u], mid + 1, r, ql, qr, qv, xy); } else { result += fast_in(left_son[u], l, mid, ql, mid, qv, xy); result += fast_in(right_son[u], mid + 1, r, mid + 1, qr, qv, xy); } sum[u] -= result; return result; } }; function<void (vector<int> &, int, int, int, int, int, int, int, int)> fast_out = [&] (vector<int> &root, int u, int l, int r, int pos, int ql, int qr, int qv, int xy) { fast_in(root[u], 0, MAX - 1, ql, qr, qv, xy); if (l == r) { return; } else { int mid = (l + r) / 2, x = u + 1, y = u + (mid - l + 1) * 2; if (pos <= mid) { fast_out(root, x, l, mid, pos, ql, qr, qv, xy); } else { fast_out(root, y, mid + 1, r, pos, ql, qr, qv, xy); } } }; while (!que.empty()) { int u = que.front().first, xy = que.front().second; que.pop(); if (xy == 0) { if (range_x[u].x == tx && ty >= range_x[u].L && ty <= range_x[u].R) { cout << dis_x[u] << endl; return 0; } else { fast_out(root_y, 0, 0, MAX - 1, range_x[u].x, range_x[u].L, range_x[u].R, dis_x[u] + 1, 0); } } else { if (range_y[u].x == ty && tx >= range_y[u].L && tx <= range_y[u].R) { cout << dis_y[u] << endl; return 0; } else { fast_out(root_x, 0, 0, MAX - 1, range_y[u].x, range_y[u].L, range_y[u].R, dis_y[u] + 1, 1); } } } return 0; }

Compilation message (stderr)

golf.cpp: In function 'int main()':
golf.cpp:153:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 0; i < range_x.size(); i++) {
                   ~~^~~~~~~~~~~~~~~~
golf.cpp:159:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for (int i = 0; i < range_y.size(); i++) {
                   ~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...