Submission #817504

#TimeUsernameProblemLanguageResultExecution timeMemory
817504NothingXDMeetings (IOI18_meetings)C++17
60 / 100
5560 ms351776 KiB
#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;
};

pll lazy1[maxn << 2];
ll lazy2[maxn << 2];
Seg seg[maxn << 2];

Seg operator +(Seg a, Seg b){
	Seg res;
	res.l = a.l;
	res.r = b.r;
	return res;
}

void shift(int v, int l, int r);

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){
			seg[v].l = a + b * l;
			seg[v].r = a + b * (r-1);
			lazy1[v] = {a, b};
	//		debug(seg[v].l, seg[v].r, seg[v].mx, lazy1[v].F, lazy1[v].S);
			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);
	}
	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);
		seg[v].l += val;
		seg[v].r += val;
		lazy1[v].F += val;
		lazy2[v] += 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);
	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);
}

void shift(int v, int l, int r){
	if (lazy2[v] == 0 && lazy1[v].S == -1) return;
	int mid = (l + r) >> 1;
	if (lazy2[v] != 0){
		add(v << 1, l, mid, l, mid, lazy2[v]);
		add(v << 1 | 1, mid, r, mid, r, lazy2[v]);
	}
	if (lazy1[v].S != -1){
		change(v << 1, l, mid, l, mid, lazy1[v].F, lazy1[v].S);
		change(v << 1 | 1, mid, r, mid, r, lazy1[v].F, lazy1[v].S);
	}
	lazy1[v] = {0, -1};
	lazy2[v] = 0;
}

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 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] = {0, 0};
		lazy1[i] = {0, -1};
		lazy2[i] = 0;
	}
	for (int i = 0; i < n; i++){
		if (!flg){
			val.push_back({h[i], i});
			rmq[0][i] = {h[i], i};
		}
		else{
			val.push_back({h[i], -i});
			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});
	}
	sort(all(val));
	for (auto [x, y]: val){
		y = abs(y);
//		debug(x, y);
		for (auto [tmp, idx]: Q[y]){
			ans[idx] = min(ans[idx], get(1, 0, n, tmp.S) + 1ll * (y-tmp.F+1) * x);
		}
		int l = -1, r = y;
		while(l + 1 < r){
			int mid = (l + r) >> 1;
			if (abs(getmx(mid, y).S) == y) r = mid;
			else l = mid;
		}
		int l2 = y, r2 = n;
		while(l2 + 1 < r2){
			int mid = (l2 + r2) >> 1;
			if (abs(getmx(y, mid).S) == y) l2 = mid;
			else r2 = mid;
		}
		add(1, 0, n, y, r2, 1ll * (y-l) * x);
		if (r == y) continue;
		ll tmp = get(1, 0, n, y-1);
		tmp -= 1ll * (y-1) * x;
		change(1, 0, n, y, r2, tmp, x);
	}
}

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 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...