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 77 78 79
| #include <cstdio> #include <cstdlib> #define Tree1 Tree[0] #define Tree2 Tree[1] #define Tree3 Tree[2] #define int long long #define INF 100000000000000000LL
inline int min(const int x, const int y) {return x < y ? x : y;} inline int abs(const int k) {return k >= 0 ? k : -k;} int x[200005], tot; struct Segment_tree { struct Node { int l, r, v, Lazy; } c[1000005]; void make_tree(const int O, const int L, const int R) { c[O].l = L, c[O].r = R, c[O].v = INF; if (L != R) { make_tree(O << 1, L, L + R >> 1); make_tree(O << 1 | 1, (L + R >> 1) + 1, R); } } void pushdown(const int O) { c[O << 1].v += c[O].Lazy, c[O << 1].Lazy += c[O].Lazy; c[O << 1 | 1].v += c[O].Lazy, c[O << 1 | 1].Lazy += c[O].Lazy; c[O].Lazy = 0LL; } void update(const int O, const int p, const int d) { if (c[O].l == c[O].r) {c[O].v = min(c[O].v, d); return;} pushdown(O); const int mid(c[O].l + c[O].r >> 1); if (p <= mid) update(O << 1, p, d); else update(O << 1 | 1, p, d); c[O].v = min(c[O << 1].v, c[O << 1 | 1].v); } void Add(const int O, const int L, const int R, const int d) { if (L > R) return; if (L <= c[O].l && c[O].r <= R) {c[O].v += d, c[O].Lazy += d; return;} const int mid(c[O].l + c[O].r >> 1); pushdown(O); if (L <= mid) Add(O << 1, L, R, d); if (mid < R) Add(O << 1 | 1, L, R, d); c[O].v = min(c[O << 1].v, c[O << 1 | 1].v); } int query(const int O, const int L, const int R) { if (L > R) return INF; if (L <= c[O].l && c[O].r <= R) return c[O].v; const int mid(c[O].l + c[O].r >> 1); pushdown(O); int ans(INF); if (L <= mid) ans = min(ans, query(O << 1, L, R)); if (mid < R) ans = min(ans, query(O << 1 | 1, L, R)); return ans; } } Tree[3];
signed main() { int n, q, A, B; scanf("%lld%lld%lld%lld", &n, &q, &A, &B); Tree1.make_tree(1, 1, n); Tree2.make_tree(1, 1, n); Tree3.make_tree(1, 1, n); x[tot = 1] = A; Tree1.update(1, B, -B); Tree2.update(1, B, B); Tree3.update(1, B, 0); while (q --) { ++ tot; scanf("%lld", &x[tot]); int ret(min(x[tot] + Tree1.query(1, 1, x[tot]), Tree2.query(1, x[tot], n) - x[tot])), add(); for (int i(0); i <= 2; ++ i) Tree[i].Add(1, 1, n, abs(x[tot] - x[tot - 1])); Tree1.update(1, x[tot - 1], ret - x[tot - 1]); Tree2.update(1, x[tot - 1], ret + x[tot - 1]); Tree3.update(1, x[tot - 1], ret); } printf("%lld", Tree3.query(1, 1, n)); return 0; }
|