Submission #1134638

#TimeUsernameProblemLanguageResultExecution timeMemory
1134638alterioNile (IOI24_nile)C++20
23 / 100
2096 ms19124 KiB
#include "nile.h"
#include <bits/stdc++.h>

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,unroll-loops")

using namespace std;

#define ll long long
#define all(x) (x).begin(), (x).end()

struct S {
	ll w, a, b;
};

bool csort(S a, S b) {
	if (a.w != b.w) return a.w < b.w;
	return a.a < b.a;
}

vector<ll> calculate_costs(vector<int> W, vector<int> A, vector<int> B, vector<int> E) {
    int N = A.size(), Q = (int) E.size();
	vector<pair<ll, ll>> ord;
	for (int i = 0; i < Q; i++) ord.push_back({E[i], i});
	sort(all(ord));
	vector<S> V;
	for (int i = 0; i < N; i++) V.push_back({W[i], A[i], B[i]});
	sort(all(V), csort);
    vector<ll> res(Q, 0);
	ll ans = 0;
	set<pair<ll, pair<ll, ll>>> s;
	s.insert({-1e10, {-1e10, 0}});
	s.insert({1e10, {1e10, 0}});
	for (int i = 0; i < N; i++) {
		s.insert({i, {i, V[i].a}});
		ans += V[i].a;
	}
	ll prf[N + 2];
	memset(prf, 0, sizeof(prf));
	prf[0] = V[0].b;
	for (int i = 1; i < N; i++) prf[i] = prf[i - 1] + V[i].b;
	auto get = [&] (int l, int r) {
		if (l < 0 || r >= N || l > r) return 0LL;
		return prf[r] - (l == 0 ? 0 : prf[l - 1]);
	};
	for (auto x : ord) {
		vector<pair<ll, pair<ll, ll>>> toDelete, toAdd;
		auto it = s.begin();
		it++;
		auto nxt = it;
		nxt++;
		vector<pair<ll, pair<ll, ll>>> cont;
		while (1) {
			ll first = it->second.first, last = nxt->first;
			if (last == 1e10) break;
			if (V[last].w - V[first].w <= x.first) {
				if (!cont.size()) cont.push_back(*it), toDelete.push_back(*it);
				toDelete.push_back(*nxt);
				cont.push_back(*nxt);
			}
			else if (cont.size()) {
				ll l = cont[0].first, r = cont.back().second.first;
				ll len = r - l + 1;
				if (len % 2 == 0) toAdd.push_back({l, {r, get(l, r)}});
				else {
					ll newAns = 1e15;
					for (int i = 0; i < cont.size(); i++) {
						int posL = cont[i].first, posR = cont[i].second.first;
						if ((posR - posL + 1) % 2 == 1) {
							ll sum = cont[i].second.second;
							sum += get(l, posL - 1);
							sum += get(posR + 1, r);
							newAns = min(newAns, sum);
						}
					}
					for (int i = 0; i < cont.size(); i++) {
						int posL = cont[i].first, posR = cont[i].second.first;
						if (i) {
							if ((posL - l) % 2 == 0) newAns = min(newAns, get(l, posL - 1) + V[posL].a + get(posL + 1, r));
							else if (V[posL + 1].w - V[posL - 1].w <= x.first) newAns = min(newAns, get(l, posL - 1) + V[posL].a + get(posL + 1, r));
						}
						if (i + 1 < cont.size()) {
							if ((r - posR) % 2 == 0) newAns = min(newAns, get(l, posR - 1) + V[posR].a + get(posR + 1, r));
							else if (V[posR + 1].w - V[posR - 1].w <= x.first) newAns = min(newAns, get(l, posR - 1) + V[posR].a + get(posR + 1, r));
						}
					}
					toAdd.push_back({l, {r, newAns}});
				}
				cont.clear();
			}
			it++;
			nxt++;
		}
		if (cont.size()) {
			ll l = cont[0].first, r = cont.back().second.first;
			ll len = r - l + 1;
			if (len % 2 == 0) toAdd.push_back({l, {r, get(l, r)}});
			else {
				ll newAns = 1e15;
				for (int i = 0; i < cont.size(); i++) {
					int posL = cont[i].first, posR = cont[i].second.first;
					if ((posR - posL + 1) % 2 == 1) {
						ll sum = cont[i].second.second;
						sum += get(l, posL - 1);
						sum += get(posR + 1, r);
						newAns = min(newAns, sum);
					}
				}
				for (int i = 0; i < cont.size(); i++) {
					int posL = cont[i].first, posR = cont[i].second.first;
					if (i) {
						if ((posL - l) % 2 == 0) newAns = min(newAns, get(l, posL - 1) + V[posL].a + get(posL + 1, r));
						else if (V[posL + 1].w - V[posL - 1].w <= x.first) newAns = min(newAns, get(l, posL - 1) + V[posL].a + get(posL + 1, r));
					}
					if (i + 1 < cont.size()) {
						if ((r - posR) % 2 == 0) newAns = min(newAns, get(l, posR - 1) + V[posR].a + get(posR + 1, r));
						else if (V[posR + 1].w - V[posR - 1].w <= x.first) newAns = min(newAns, get(l, posR - 1) + V[posR].a + get(posR + 1, r));
					}
				}
				toAdd.push_back({l, {r, newAns}});
			}
		}
		for (auto el : toDelete) {
			s.erase(s.find(el));
			ans -= el.second.second;
		}
		for (auto el : toAdd) {
			s.insert(el);
			ans += el.second.second;
		}
		res[x.second] = ans;
	}
    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...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...