#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep2(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define rrep(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define rrep2(i, a, b) for (int i = (int)(b) - 1; i >= (int)(a); --i)
#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
using namespace std;
using ll = long long;
using PLL = pair<ll, ll>;
template<class T, class U> bool chmin(T& a, const U& b) { return a > b ? a = b, true : false; }
template<class T, class U> bool chmax(T& a, const U& b) { return a < b ? a = b, true : false; }
constexpr ll inf = 1e18;
constexpr int infty = 2e9;
constexpr int dx[] = {0, 1, 0, -1};
constexpr int dy[] = {1, 0, -1, 0};
int main() {
int sx, sy, tx, ty; scanf("%d%d%d%d", &sx, &sy, &tx, &ty);
int N; scanf("%d", &N);
vector<array<int, 4>> A(N);
rep (i, N) rep (j, 4) scanf("%d", &A[i][j]);
vector<int> Xs{-infty, sx, tx, infty}, Ys{-infty, sy, ty, infty};
rep (i, N) {
Xs.push_back(A[i][0]);
Xs.push_back(A[i][1]);
Ys.push_back(A[i][2]);
Ys.push_back(A[i][3]);
}
sort(all(Xs)); Xs.erase(unique(all(Xs)), Xs.end());
sort(all(Ys)); Ys.erase(unique(all(Ys)), Ys.end());
sx = lower_bound(all(Xs), sx) - Xs.begin();
tx = lower_bound(all(Xs), tx) - Xs.begin();
sy = lower_bound(all(Ys), sy) - Ys.begin();
ty = lower_bound(all(Ys), ty) - Ys.begin();
rep (i, N) {
A[i][0] = lower_bound(all(Xs), A[i][0]) - Xs.begin();
A[i][1] = lower_bound(all(Xs), A[i][1]) - Xs.begin();
A[i][2] = lower_bound(all(Ys), A[i][2]) - Ys.begin();
A[i][3] = lower_bound(all(Ys), A[i][3]) - Ys.begin();
}
int H = Xs.size(), W = Ys.size();
vector<ll> L(4 * N + 4), R(4 * N + 4), D(4 * N + 4);
{
map<int, vector<tuple<int, int, int, int>>> mp;
rep (i, N) {
mp[A[i][0]].emplace_back(i, 0, A[i][2], i * 4 + 0);
mp[A[i][1]].emplace_back(i, 1, A[i][2], i * 4 + 1);
}
mp[sx].emplace_back(-1, -1, sy, 4 * N + 0);
mp[tx].emplace_back(-1, -1, ty, 4 * N + 1);
set<int> st{0, W - 1};
for (auto [y, v] : mp) {
for (auto [i, t, x, j] : v) {
if (t == 1) {
st.erase(A[i][2]);
st.erase(A[i][3]);
}
}
for (auto [i, t, x, j] : v) {
L[j] = *--st.upper_bound(x);
R[j] = *st.lower_bound(x) + 1;
D[j] = y;
}
for (auto [i, t, x, j] : v) {
if (t == 0) {
st.insert(A[i][2]);
st.insert(A[i][3]);
}
}
}
}
{
map<int, vector<tuple<int, int, int, int>>> mp;
rep (i, N) {
mp[A[i][2]].emplace_back(i, 0, A[i][0], i * 4 + 2);
mp[A[i][3]].emplace_back(i, 1, A[i][0], i * 4 + 3);
}
mp[sy].emplace_back(-1, -1, sx, 4 * N + 2);
mp[ty].emplace_back(-1, -1, tx, 4 * N + 3);
set<int> st{0, H - 1};
for (auto [y, v] : mp) {
for (auto [i, t, x, j] : v) {
if (t == 1) {
st.erase(A[i][0]);
st.erase(A[i][1]);
}
}
for (auto [i, t, x, j] : v) {
L[j] = *--st.upper_bound(x);
R[j] = *st.lower_bound(x) + 1;
D[j] = y;
}
for (auto [i, t, x, j] : v) {
if (t == 0) {
st.insert(A[i][0]);
st.insert(A[i][1]);
}
}
}
}
vector<vector<int>> G(4 * N + 4);
auto new_vertex = [&] {
int sz = G.size();
G.emplace_back();
return sz;
};
{
vector<vector<int>> qs(W), ns(W + 1);
rep (i, 4 * N + 4) {
if (i % 4 / 2 == 1) qs[D[i]].push_back(i);
else {
ns[L[i]].push_back(i);
ns[R[i]].push_back(-i - 1);
}
}
int M = 1;
while (M < H) M *= 2;
vector<int> dat(2 * M, -1);
rep (x, W) {
for (auto t : ns[x]) {
if (t >= 0) {
int i = t;
int k = D[i] + M;
dat[k] = i;
while (k > 1) {
k /= 2;
int a = dat[k * 2], b = dat[k * 2 + 1];
if (a == -1) dat[k] = b;
else if (b == -1) dat[k] = a;
else {
int v = new_vertex();
dat[k] = v;
G[v].push_back(a);
G[v].push_back(b);
}
}
}
}
for (auto t : qs[x]) {
int l = L[t] + M, r = R[t] + M;
while (l < r) {
if (l & 1) {
if (dat[l] != -1) G[t].push_back(dat[l]);
++l;
}
if (r & 1) {
--r;
if (dat[r] != -1) G[t].push_back(dat[r]);
}
l /= 2; r /= 2;
}
}
for (auto t : ns[x]) {
if (t < 0) {
int i = -t - 1;
int k = D[i] + M;
dat[k] = -1;
while (k > 1) {
k /= 2;
int a = dat[k * 2], b = dat[k * 2 + 1];
if (a == -1) dat[k] = b;
else if (b == -1) dat[k] = a;
else {
int v = new_vertex();
dat[k] = v;
G[v].push_back(a);
G[v].push_back(b);
}
}
}
}
}
}
{
vector<vector<int>> qs(H), ns(H + 1);
rep (i, 4 * N + 4) {
if (i % 4 / 2 == 0) qs[D[i]].push_back(i);
else {
ns[L[i]].push_back(i);
ns[R[i]].push_back(-i - 1);
}
}
int M = 1;
while (M < W) M *= 2;
vector<int> dat(2 * M, -1);
rep (x, H) {
for (auto t : ns[x]) {
if (t >= 0) {
int i = t;
int k = D[i] + M;
dat[k] = i;
while (k > 1) {
k /= 2;
int a = dat[k * 2], b = dat[k * 2 + 1];
if (a == -1) dat[k] = b;
else if (b == -1) dat[k] = a;
else {
int v = new_vertex();
dat[k] = v;
G[v].push_back(a);
G[v].push_back(b);
}
}
}
}
for (auto t : qs[x]) {
int l = L[t] + M, r = R[t] + M;
while (l < r) {
if (l & 1) {
if (dat[l] != -1) G[t].push_back(dat[l]);
++l;
}
if (r & 1) {
--r;
if (dat[r] != -1) G[t].push_back(dat[r]);
}
l /= 2; r /= 2;
}
}
for (auto t : ns[x]) {
if (t < 0) {
int i = -t - 1;
int k = D[i] + M;
dat[k] = -1;
while (k > 1) {
k /= 2;
int a = dat[k * 2], b = dat[k * 2 + 1];
if (a == -1) dat[k] = b;
else if (b == -1) dat[k] = a;
else {
int v = new_vertex();
dat[k] = v;
G[v].push_back(a);
G[v].push_back(b);
}
}
}
}
}
}
auto bfs = [&](int s, int t) -> ll {
if (s % 4 / 2 == t % 4 / 2 && L[s] == L[t] && R[s] == R[t] && D[s] == D[t]) return 1;
vector<ll> dist(G.size(), inf);
deque<PLL> que;
dist[s] = 0;
que.emplace_front(s, 0);
while (!que.empty()) {
auto [v, c] = que.front(); que.pop_front();
if (dist[v] != c) continue;
for (int e : G[v]) {
ll nc = c + (e < 4 * N + 4);
if (chmin(dist[e], nc)) {
if (e < 4 * N + 4) que.emplace_back(e, nc);
else que.emplace_front(e, nc);
}
}
}
return dist[t] + 1;
};
ll ans = inf;
chmin(ans, bfs(4 * N + 0, 4 * N + 1));
chmin(ans, bfs(4 * N + 2, 4 * N + 1));
chmin(ans, bfs(4 * N + 0, 4 * N + 3));
chmin(ans, bfs(4 * N + 2, 4 * N + 3));
printf("%lld\n", ans);
}
Compilation message (stderr)
golf.cpp: In function 'int main()':
golf.cpp:25:30: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
25 | int sx, sy, tx, ty; scanf("%d%d%d%d", &sx, &sy, &tx, &ty);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
golf.cpp:26:17: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
26 | int N; scanf("%d", &N);
| ~~~~~^~~~~~~~~~
golf.cpp:28:32: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
28 | rep (i, N) rep (j, 4) scanf("%d", &A[i][j]);
| ~~~~~^~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |