Submission #548821

#TimeUsernameProblemLanguageResultExecution timeMemory
548821enerelt14Safety (NOI18_safety)C++14
100 / 100
79 ms6324 KiB
#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...