This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "meetings.h"
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef double ld;
typedef complex<ld> point;
void debug_out(){cerr << endl;}
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T){
cerr << H << ' ';
debug_out(T...);
}
#define debug(...) cerr << "(" << #__VA_ARGS__ << "): ", debug_out(__VA_ARGS__)
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define MP(x, y) make_pair(x, y)
const int maxn = 1e6 + 10;
struct Seg{
ll l, r, lazy2;
pll lazy1;
};
Seg seg[maxn << 2];
void merge(int v)
{
seg[v].l = seg[v << 1].l;
seg[v].r = seg[v << 1 | 1].r;
}
//void shift(int v, int l, int r);
void update1(int v, int l, int r, ll a, ll b){
seg[v].l = a + b * l;
seg[v].r = a + b * (r-1);
seg[v].lazy1 = {a, b};
}
void update2(int v, int l, int r, ll val){
seg[v].l += val;
seg[v].r += val;
seg[v].lazy1.F += val;
seg[v].lazy2 += val;
}
void shift(int v, int l, int r){
if (seg[v].lazy2 == 0 && seg[v].lazy1.S == -1) return;
int mid = (l + r) >> 1;
if (seg[v].lazy2 != 0){
update2(v << 1, l, mid, seg[v].lazy2);
update2(v << 1 | 1, mid, r, seg[v].lazy2);
}
if (seg[v].lazy1.S != -1){
update1(v << 1, l, mid, seg[v].lazy1.F, seg[v].lazy1.S);
update1(v << 1 | 1, mid, r, seg[v].lazy1.F, seg[v].lazy1.S);
}
seg[v].lazy1 = {0, -1};
seg[v].lazy2 = 0;
}
void change(int v, int l, int r, int ql, int qr, ll a, ll b){
// if (v == 1) debug(ql, qr, a, b);
if (qr <= l || r <= ql) return;
if (!(ql <= l && r <= qr)){
shift(v, l, r);
int mid = (l + r) >> 1;
change(v << 1, l, mid, ql, qr, a, b);
change(v << 1 | 1, mid, r, ql, qr, a, b);
}
else{
// debug(v, l, r, ql, qr, a, b, seg[v].l, seg[v].r);
if (a + b * l <= seg[v].l && a + b * (r-1) <= seg[v].r){
// debug(seg[v].l, seg[v].r, seg[v].mx, seg[v].lazy1.F, seg[v].lazy1.S);
update1(v, l, r, a, b);
return;
}
if (a + b * l >= seg[v].l && a + b * (r-1) >= seg[v].r) return;
shift(v, l, r);
int mid = (l + r) >> 1;
change(v << 1, l, mid, ql, qr, a, b);
change(v << 1 | 1, mid, r, ql, qr, a, b);
}
merge(v);
//seg[v] = seg[v << 1] + seg[v << 1 | 1];
}
void add(int v, int l, int r, int ql, int qr, ll val){
//if (v == 1) debug(ql, qr, val);
if (qr <= l || r <= ql) return;
if (ql <= l && r <= qr){
// debug(v, l, r, ql, qr, val);
update2(v, l, r, val);
return;
}
shift(v, l, r);
int mid = (l + r) >> 1;
add(v << 1, l, mid, ql, qr, val);
add(v << 1 | 1, mid, r, ql, qr, val);
merge(v);
//seg[v] = seg[v << 1] + seg[v << 1 | 1];
}
ll get(int v, int l, int r, int idx){
//if (v == 1) debug(idx);
if (l + 1 == r) return seg[v].l;
shift(v, l, r);
int mid = (l + r) >> 1;
if (idx < mid) return get(v << 1, l, mid, idx);
else return get(v << 1 | 1, mid, r, idx);
}
const int lg = 20;
const ll inf = 1e18;
int n, q, h[maxn], queryl[maxn], queryr[maxn];
ll ans[maxn];
pii rmq[lg][maxn];
vector<pair<pii,int>> Q[maxn];
pii getmx(int l, int r){
r++;
int x = 31 - __builtin_clz(r-l);
return max(rmq[x][l], rmq[x][r-(1<<x)]);
}
void carttree(int l, int r){
if (r < l) return;
int mid = getmx(l, r).S;
mid = abs(mid);
carttree(l, mid-1);
carttree(mid+1, r);
// debug(x, y);
for (auto [tmp, idx]: Q[mid]){
ans[idx] = min(ans[idx], get(1, 0, n, tmp.S) + 1ll * (mid-tmp.F+1) * h[mid]);
}
add(1, 0, n, mid, r+1, 1ll * (mid-l+1) * h[mid]);
if (l == mid) return;
ll tmp = get(1, 0, n, mid-1);
tmp -= 1ll * (mid-1) * h[mid];
change(1, 0, n, mid, r+1, tmp, h[mid]);
}
void solve(bool flg){
vector<pii> val;
for (int i = 0; i < n; i++){
Q[i].clear();
}
for (int i = 1; i < 4*maxn; i++){
seg[i].l = 0;
seg[i].r = 0;
seg[i].lazy1 = {0, -1};
seg[i].lazy2 = 0;
}
for (int i = 0; i < n; i++){
if (!flg){
rmq[0][i] = {h[i], i};
}
else{
rmq[0][i] = {h[i], -i};
}
}
for (int i = 1; i < lg; i++){
for (int j = 0; j + (1 << i) <= n; j++){
rmq[i][j] = max(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]);
}
}
for (int i = 0; i < q; i++){
int mx = abs(getmx(queryl[i], queryr[i]).S);
Q[mx].push_back({{queryl[i], queryr[i]}, i});
}
carttree(0, n-1);
}
vector<ll> minimum_costs(vector<int> H, vector<int> L, vector<int> R) {
n = H.size();
q = L.size();
for (int i = 0; i < n; i++){
h[i] = H[i];
}
for (int i = 0; i < q; i++){
queryl[i] = L[i];
queryr[i] = R[i];
ans[i] = inf;
}
solve(false);
// debug("----------------");
// for (int i = 0; i < q; i++) debug(i, ans[i]);
for (int i = 0; i < q; i++){
queryl[i] = n-R[i]-1;
queryr[i] = n-L[i]-1;
}
for (int i = 0; i < n/2; i++){
swap(h[i], h[n-i-1]);
}
solve(true);
vector<ll> res;
for (int i = 0; i < q; i++) res.push_back(ans[i]);
return res;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |