1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <queue> #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> using namespace std;
template<typename TT> inline void read(TT &x) {}
const int N = 2e5 + 9;
struct Node { int x1, y1, x2, y2; }; struct Point { int x, y, opt, id; };
int n, m, cnt; int f[N], ans[N], len[N]; Node a[N]; Point p[N];
inline int calc_dis(int x1, int y1, int x2, int y2) { return x2 - x1 + y2 - y1; }
inline bool cmp_x(const Point &i, const Point &j) { if (i.x == j.x) { if (i.y == j.y) return i.opt > j.opt; return i.y < j.y; } return i.x < j.x; } inline bool cmp_y(const Point &i, const Point &j) { if (i.y == j.y) { if (i.x == j.x) return i.opt > j.opt; return i.x < j.x; } return i.y < j.y; }
void CDQ(int l, int r) { if (l == r) return; int mid = (l + r) >> 1; CDQ(l, mid), sort(p+mid+1, p+r+1, cmp_y); int maxn = 0; for (int i = mid+1, j = l, k = -1; i <= r; ++i) { if (p[i].opt) continue; int id = p[i].id; while (j <= mid && p[j].y <= p[i].y) { if (p[j].opt) maxn = max(maxn, ans[p[j].id]); j++; } ans[p[i].id] = max(ans[p[i].id], maxn + len[p[i].id]); } sort(p+mid+1, p+r+1, cmp_x); CDQ(mid+1, r); sort(p+l, p+r+1, cmp_y); }
int main() { read(n), read(m); for (int i = 1; i <= m; ++i) read(a[i].x1), read(a[i].y1), read(a[i].x2), read(a[i].y2); for (int i = 1; i <= m; ++i) p[++cnt] = (Point){a[i].x1, a[i].y1, 0, i}, p[++cnt] = (Point){a[i].x2, a[i].y2, 1, i}; p[++cnt] = (Point){0, 0, 1, 0}, p[++cnt] = (Point){n, n, 0, m+1}; sort(p+1, p+cnt+1, cmp_x); for (int i = 1; i <= m; ++i) len[i] = calc_dis(a[i].x1, a[i].y1, a[i].x2, a[i].y2); CDQ(1, cnt); printf("%d\n", n + n - ans[m+1]); return 0; }
|