# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
1241621 | Zero_OP | Safety (NOI18_safety) | C11 | 0 ms | 0 KiB |
//CAUTION : this template is only suitable with C++17 (above) and home training, do not abuse when practicing offline
#include <bits/stdc++.h>
using namespace std;
//Benq inspires me lol
#define tcT template<class T
#define tcTU tcT, class U
//pairs
#define mp make_pair
#define mt make_tuple
#define ff first
#define ss second
//vectors
#define sz(v) (int)v.size()
#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define pb push_back
#define eb emplace_back
#define compact(v) v.erase(unique(all(v)), end(v))
tcT> int lwb(const vector<T>& a, const T& b){ return int(lower_bound(all(a), b) - begin(a)); }
tcT> int upb(const vector<T>& a, const T& b){ return int(upper_bound(all(a), b) - begin(a)); }
//loops (warning : ONLY for int)
#define rep(i, l, r) for(int i = (l); i < (r); ++i)
#define FOR(i, l, r) for(int i = (l); i <= (r); ++i)
//debug
#define dbg(x) "[" #x " = " << (x) << "]"
//data types
using ll = long long;
using db = double;
using ld = long double;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vi = vector<int>;
using vl = vector<ll>;
using vb = vector<bool>;
using vd = vector<db>;
using vc = vector<char>;
using vstr = vector<string>;
using vpi = vector<pi>;
using vpl = vector<pl>;
tcT> using min_heap = priority_queue<T, vector<T>, greater<T>>;
tcT> using max_heap = priority_queue<T>;
//bitwise operations
#define popcount(x) __builtin_popcountll(x) //count bits
#define BIT(k) (1LL << k) //bit k-th
#define all_bits(k) ((1LL << k) - 1) //first k bits on
//functions
tcT> bool minimize(T& a, const T& b){ if(a > b) return a = b, true; return false; }
tcT> bool maximize(T& a, const T& b){ if(a < b) return a = b, true; return false; }
tcT> T ceil_div(T a, T b){ return (a / b) + ((a ^ b) > 0 && a % b); }
tcT> T floor_div(T a, T b){ return (a / b) - ((a ^ b) < 0 && a % b); }
tcTU> T first_true(T lo, T hi, U f){ //if no exist then return hi+1
++hi; assert(lo <= hi);
while(lo < hi){ //[lo, hi)
T mid = (lo + hi) >> 1;
f(mid) ? hi = mid : lo = mid + 1;
}
return lo;
}
tcTU> T last_true(T lo, T hi, U f){ //if no exist then return lo-1
--lo; assert(lo <= hi);
while(lo < hi){ //(lo, hi]
T mid = (lo + hi) >> 1;
f(mid) ? lo = mid : hi = mid - 1;
}
return lo;
}
tcT> void safe_erase(vector<T>& a, T x){
auto it = find(all(a), x);
if(it != a.end()) a.erase(it);
}
#ifdef LOCAL //for checking time elapsed
const auto start_time = std::chrono::high_resolution_clock::now();
db time_elapsed(){ return chrono::duration<db>(std::chrono::high_resolution_clock::now() -
start_time).count(); }
#endif //LOCAL
void setIO(){
ios_base::sync_with_stdio(0); cin.tie(0);
#define task "task"
if(fopen(task".inp", "r")){
freopen(task".inp", "r", stdin);
// freopen(task".out", "w", stdout);
}
}
struct SlopeTrick{
ll offset, min_f, shift;
max_heap<ll> L;
min_heap<ll> R;
SlopeTrick(ll H) : offset(0), shift(H), L(), R(), min_f(0) {}
//add function |x - a| = max(0, x - a) + max(0, a - x)
void add_abs_func(ll a){
if(L.empty() && R.empty()){ //initial
offset += shift;
L.push(a);
R.push(a);
return;
}
assert(!L.empty());
assert(!R.empty());
ll low = L.top() - offset, high = R.top() + offset; //optimum range [low, high]
// cout << dbg(low) << dbg(high) << '\n';
if(a < low){ //increase min_f
// cout << "c\n";
min_f += low - a;
L.pop();
R.push(low + offset);
L.push(a - offset);
R.push(a - offset);
offset += shift;
} else if(high < a){ //increase min_f
// cout << "cc\n";
min_f += a - high;
R.pop();
R.push(high - offset);
R.push(a - offset);
R.push(a - offset);
offset += shift;
} else{ //keep min_f
// cout << "ccc\n";
L.push(a - offset);
R.push(a - offset);
//apply shifting to make f_i(x) -> g_i(x)
offset += shift;
}
// cout << dbg(min_f) << '\n';
}
pl optimum(){
assert(!L.empty() && !R.empty());
return mp(L.top() - offset, R.top() + offset);
}
void output(){
vl slopes;
auto P = L;
auto Q = R;
while(!P.empty()){
ll it = P.top(); P.pop();
slopes.pb(it - offset);
}
while(!Q.empty()){
ll it = Q.top(); Q.pop();
slopes.pb(it + offset);
}
sort(all(slopes));
for(auto it : slopes) cout << it << ' '; cout << '\n';
}
};
void testcase(int n_case){
int N, H;
cin >> N >> H;
vl a(N);
rep(i, 0, N) cin >> a[i];
SlopeTrick st(H);
rep(i, 0, N){
// cout << dbg(a[i]) << '\n';
st.add_abs_func(a[i]);
// auto [low, high] = st.optimum();
// cout << low << ' ' << high << '\n';
// st.output();
// cout << '\n';
}
cout << st.min_f << '\n';
}
int main(){
setIO();
int T = 1;
// cin >> T;
rep(i, 0, T) testcase(i);
#ifdef LOCAL
cerr << '\n' << "Execution time : " << (time_elapsed() * 1000.0) << " ms";
#endif //LOCAL
return 0;
}