Submission #547022

#TimeUsernameProblemLanguageResultExecution timeMemory
547022gimabd30Safety (NOI18_safety)C++17
100 / 100
71 ms6324 KiB
//#define _GLIBCXX_DEBUG

//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

using namespace std;

#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;

template<typename T>
using ordered_set = tree<T, null_type, less < T>, rb_tree_tag, tree_order_statistics_node_update>;

template<typename T>
using normal_queue = priority_queue <T, vector<T>, greater<>>;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());

#define ll long long
#define trace(x) cout << #x << ": " << (x) << endl;
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)
#define uniq(x) x.resize(unique(all(x)) - begin(x))
#define ld long double
#define sz(s) ((int) size(s))
#define pii pair<int, int>
#define mp(x, y) make_pair(x, y)
#define int128 __int128
#define pb push_back
#define eb emplace_back


template<typename T>
bool ckmin(T &x, T y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}

template<typename T>
bool ckmax(T &x, T y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}

int bit(int x, int b) {
    return (x >> b) & 1;
}


int rand(int l, int r) { return (int) ((ll) rnd() % (r - l + 1)) + l; }

//soryan za musor sverhu

const ll infL = 3e18;
const int infI = 1e9 + 7;
const int N = 300001;
const ll mod = 1e9 + 7;
const ld eps = 1e-9;

template<typename T>
struct SlopeTrick {

    const T INF = numeric_limits<T>::max() / 3;

    T min_f;
    priority_queue <T, vector<T>, less<>> L;
    priority_queue <T, vector<T>, greater<>> R;
    T add_l, add_r;

    void push_R(const T &a) {
        R.push(a - add_r);
    }

    T top_R() const {
        if (R.empty()) return INF;
        else return R.top() + add_r;
    }

    T pop_R() {
        T val = top_R();
        if (not R.empty()) R.pop();
        return val;
    }

    void push_L(const T &a) {
        L.push(a - add_l);
    }

    T top_L() const {
        if (L.empty()) return -INF;
        else return L.top() + add_l;
    }

    T pop_L() {
        T val = top_L();
        if (not L.empty()) L.pop();
        return val;
    }

    size_t size() {
        return L.size() + R.size();
    }

public:
    SlopeTrick() : min_f(0), add_l(0), add_r(0) {}

    struct Query {
        T lx, rx, min_f;
    };

    // return min f(x)
    Query query() const {
        return (Query) {top_L(), top_R(), min_f};
    }

    // f(x) += a
    void add_all(const T &a) {
        min_f += a;
    }

    // add \_
    // f(x) += max(a - x, 0)
    void add_a_minus_x(const T &a) {
        min_f += max(T(0), a - top_R());
        push_R(a);
        push_L(pop_R());
    }

    // add _/
    // f(x) += max(x - a, 0)
    void add_x_minus_a(const T &a) {
        min_f += max(T(0), top_L() - a);
        push_L(a);
        push_R(pop_L());
    }

    // add \/
    // f(x) += abs(x - a)
    void add_abs(const T &a) {
        add_a_minus_x(a);
        add_x_minus_a(a);
    }

    // \/ -> \_
    // f_{new} (x) = min f(y) (y <= x)
    void clear_right() {
        while (not R.empty()) R.pop();
    }

    // \/ -> _/
    // f_{new} (x) = min f(y) (y >= x)
    void clear_left() {
        while (not L.empty()) L.pop();
    }

    // \/ -> \_/
    // f_{new} (x) = min f(y) (x-b <= y <= x-a)
    void shift(const T &a, const T &b) {
        assert(a <= b);
        add_l += a;
        add_r += b;
    }

    // \/. -> .\/
    // f_{new} (x) = f(x - a)
    void shift(const T &a) {
        shift(a, a);
    }

    // L, R will be destroyed(((((
    T get(const T &x) {
        T ret = min_f;
        while (not L.empty()) {
            ret += max(T(0), pop_L() - x);
        }
        while (not R.empty()) {
            ret += max(T(0), x - pop_R());
        }
        return ret;
    }

    void mrg(SlopeTrick &st) {
        if (st.size() > size()) {
            swap(st.L, L);
            swap(st.R, R);
            swap(st.add_l, add_l);
            swap(st.add_r, add_r);
            swap(st.min_f, min_f);
        }
        while (not st.R.empty()) {
            add_x_minus_a(st.pop_R());
        }
        while (not st.L.empty()) {
            add_a_minus_x(st.pop_L());
        }
        min_f += st.min_f;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int test = 1;
//    cin >> test;
    while (test--) {
        int n, h;
        cin >> n >> h;
        vector<int> a(n);
        for (int i = 0; i < n; ++i) cin >> a[i];
        SlopeTrick<ll> st;
        st.add_abs(a[0]);
        for (int i = 1; i < n; ++i) {
            st.shift(-h, h);
            st.add_abs(a[i]);
        }
        cout << st.min_f;
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...