Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize("Ofast") // ������������ ���������, �� ��� ������
- #pragma GCC optimize("no-stack-protector") //�����
- #pragma GCC optimize("unroll-loops") // � ���� ���� ��� �� 100 �� ������ ����� � ��������� �� ��� � 100 ��� �� ������ ��������
- #pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native") // ��� ����� ����� �� ��� 03 02 ��������� � ������ ������� �������� ��� ���� ������������
- #pragma GCC optimize("fast-math")
- #define _CRT_SECURE_NO_WARNINGS
- #include <iostream>
- #include <vector>
- #include <string>
- #include <algorithm>
- #include <cmath>
- #include <stack>
- #include <iomanip>
- #include <fstream>
- #include <string>
- #include <set>
- #include <deque>
- #include <queue>
- #include <map>
- #include <bitset>
- #include <random>
- #include <list>
- #include <unordered_map>
- #include <unordered_set>
- #include <cassert>
- using namespace std;
- typedef long long ll;
- typedef short sh;
- typedef unsigned long long ull;
- typedef long double ld;
- typedef string str;
- //typedef __int128 ultraint;
- #define sqrt sqrtl
- #define F first
- #define S second
- #define endl '\n'
- #define all(vc666) vc666.begin(), vc666.end()
- #define allr(vc666) vc666.rbegin(), vc666.rend()
- #define int long long
- #define degug(x) cerr (#x) << " " << (x) << endl;
- const ll INF = 3e12;
- const ll inf = 1e12 + 7;
- const ll ONE = 1;
- const ll mod = 1e9 + 7;
- const ll m1 = 1e9 + 575179;
- const ll m2 = 1e9 + 87;
- const ll LG = 19;
- const ll k = 347;
- ld EPS = 1e-7;
- ld PI = 3.1415926535897932384;
- ld phi = (sqrt(5) + 1.0) / 2.0;
- mt19937_64 gen(rand());
- struct Node {
- int mn = INF, push = 0, id = -1;
- };
- struct SegTree {
- vector <Node> t;
- int n;
- SegTree(int _n) {
- n = 4 * _n;
- t.resize(n);
- }
- void unite(const Node& l, const Node& r, Node& m) {
- if (l.mn < r.mn) {
- m.mn = l.mn;
- m.id = l.id;
- }
- else {
- m.mn = r.mn;
- m.id = r.id;
- }
- m.push = 0;
- }
- void pushUP(int v) {
- t[v].mn += t[v].push;
- if (2 * v + 1 < n) {
- t[2 * v].push += t[v].push;
- t[2 * v + 1].push += t[v].push;
- }
- t[v].push = 0;
- }
- Node query(int v, int tl, int tr, int l, int r) {
- pushUP(v);
- if (tr < l || tl > r) {
- return { INF, 0, -1 };
- }
- else if (l <= tl && r >= tr) {
- return t[v];
- }
- else {
- int m = (tl + tr) / 2;
- Node L = query(2 * v, tl, m, l, r), R = query(2 * v + 1, m + 1, tr, l, r), M;
- unite(L, R, M);
- unite(t[v * 2], t[v * 2 + 1], t[v]);
- return M;
- }
- }
- void update(int v, int tl, int tr, int l, int r, int boost) {
- pushUP(v);
- if (tl > r || tr < l) {
- return;
- }
- else {
- if (tl >= l && tr <= r) {
- t[v].push += boost;
- pushUP(v);
- }
- else {
- int tm = (tl + tr) / 2;
- update(v * 2, tl, tm, l, r, boost);
- update(v * 2 + 1, tm + 1, tr, l, r, boost);
- unite(t[v * 2], t[v * 2 + 1], t[v]);
- }
- }
- }
- void build(int v, int tl, int tr, vector <int>& w) {
- if (tl == tr) {
- t[v].mn = w[tl];
- t[v].id = tl;
- }
- else {
- int tm = (tl + tr) / 2;
- build(2 * v, tl, tm, w);
- build(2 * v + 1, tm + 1, tr, w);
- unite(t[v * 2], t[v * 2 + 1], t[v]);
- }
- }
- };
- void solve() {
- int n, q, i, j, s, t;
- cin >> n >> q >> s >> t;
- s--, t--;
- vector <int> p(q);
- vector <int> w(n);
- for (i = 0; i < q; i++) {
- cin >> p[i];
- p[i]--;
- }
- for (i = 0; i < n; i++) {
- w[i] = inf + i;
- }
- SegTree t1(n), t2(n);
- t1.build(1, 0, n - 1, w);
- reverse(all(w));
- t2.build(1, 0, n - 1, w);
- t1.update(1, 0, n - 1, s, s, abs(p[0] - t) - inf);
- if (s != t) {
- t1.update(1, 0, n - 1, t, t, abs(p[0] - s) - inf);
- }
- t2.update(1, 0, n - 1, s, s, abs(p[0] - t) - inf);
- if (s != t) {
- t2.update(1, 0, n - 1, t, t, abs(p[0] - s) - inf);
- }
- Node res1, res2, el1, el2;
- int u1, u2, ans = INF;
- for (i = 0; i < q - 1; i++) {
- if (p[i + 1] == p[i]) continue;
- res1 = t2.query(1, 0, n - 1, 0, p[i + 1]);
- res2 = t1.query(1, 0, n - 1, p[i + 1], n - 1);
- el1 = t1.query(1, 0, n - 1, p[i], p[i]);
- el2 = t2.query(1, 0, n - 1, p[i], p[i]);
- u1 = res1.mn + (p[i + 1] - res1.id) - (n - res1.id - 1);
- u2 = res2.mn + (res2.id - p[i + 1]) - res2.id;
- t1.update(1, 0, n - 1, p[i], p[i], min(u1, u2) - el1.mn + p[i]);
- t2.update(1, 0, n - 1, p[i], p[i], min(u1, u2) - el2.mn + (n - p[i] - 1));
- t1.update(1, 0, n - 1, 0, p[i] - 1, abs(p[i + 1] - p[i]));
- t1.update(1, 0, n - 1, p[i] + 1, n - 1, abs(p[i + 1] - p[i]));
- t2.update(1, 0, n - 1, 0, p[i] - 1, abs(p[i + 1] - p[i]));
- t2.update(1, 0, n - 1, p[i] + 1, n - 1, abs(p[i + 1] - p[i]));
- if (i == 1) {
- /*for (j = 0; j < n; j++) {
- el1 = t1.query(1, 0, n - 1, j, j);
- cout << el1.mn << " " << el1.id << endl;
- }
- for (j = 0; j < n; j++) {
- el2 = t2.query(1, 0, n - 1, j, j);
- cout << el2.mn << " " << el2.id << endl;
- }
- for (j = 0; j < n; j++) {
- el1 = t1.query(1, 0, n - 1, j, j);
- el2 = t2.query(1, 0, n - 1, j, j);
- assert(el1.mn - el1.id == el2.mn - (n - el2.id - 1));
- cout << el1.mn - el1.id << " " << el2.mn - (n - el2.id - 1) << endl;
- }
- */
- }
- }
- for (i = 0; i < n; i++) {
- el1 = t1.query(1, 0, n - 1, i, i);
- el2 = t2.query(1, 0, n - 1, i, i);
- ans = min(ans, el1.mn - el1.id);
- ans = min(ans, el2.mn - (n - el2.id - 1));
- }
- cout << ans << endl;
- }
- signed main() {
- #ifdef _DEBUG
- freopen("input.txt", "r ", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- ios_base::sync_with_stdio(0);
- cin.tie(NULL);
- cout.tie(NULL);
- int t = 1;
- //cin >> t;
- while (t--) solve();
- }
- //Deisgned by skimono
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement