Submission #1351541

#TimeUsernameProblemLanguageResultExecution timeMemory
1351541marcogambaroNile (IOI24_nile)C++20
6 / 100
20 ms10548 KiB
#include "nile.h"
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define all(x) x.begin(),x.end()
#ifdef MARCO
#define infof(str,...) do{ fprintf(stderr, str"\n", ##__VA_ARGS__);} while(0);
#define infor(str,...) do{ fprintf(stderr, str, ##__VA_ARGS__);} while(0);
#else
#define infof(str, ...)
#define infor(str, ...)
#endif
#define pii pair<int, int>
#define pll pair<long long, long long>
#define fi first
#define se second

ll K = 0;

vector<ll> t;

void build(int v, int l, int r, vector<int> &A) {
	if(r-l == 1) {
		t[v] = A[l];
		return;
	}
	int m = (r+l)/2;
	build(v*2, l, m, A);
	build(v*2+1, m, r, A);
	t[v] = min(t[v*2], t[v*2+1]);
}
ll query(int v, int l, int r, int ql, int qr) {
	if(qr <= l || r <= ql) return 1e17;
	if(ql <= l && r <= qr) return t[v];

	int m = (l+r)/2;
	return min(query(v*2, l, m, ql, qr), query(v*2+1, m, r, ql, qr));
}

struct DSU {
	vector<ll> dsu, minA, R, m;
	vector<int> ogA;
	int N;

	DSU(vector<int> &v, vector<int> &a) {
		N = v.size();

		t.resize(4*N);
		build(1, 0, N, a);

		dsu = vector<ll>(N, -1);
		minA = m = R = vector<ll>(N, 1e17);
		for(int i=0; i<N; i++) minA[i] = a[i];
		ogA = a;
		iota(all(R), 0);
	}

	int rep(int n) {
		if(dsu[n] < 0) return n;
		return dsu[n] = rep(dsu[n]);
	}

	int size(int n) {
		return -dsu[rep(n)];
	}

	void join(int a, int b, ll t) {
		a = rep(a);
		b = rep(b);

		assert(a != b);
		if(a > b) swap(a, b);
		if(size(a)%2) K -= min(minA[a], m[a]);
		if(size(b)%2) K -= min(minA[b], m[b]);

		dsu[a] += dsu[b];
		dsu[b] = a;
		R[a] = R[b];

		if(size(a) == 2) minA[a] = 1e17;
		else minA[a] = min({(ll)ogA[a], (ll)ogA[R[a]], query(1, 0, N, a+2, R[a]-1)});

		m[a] = min(m[a], m[b]);
		if(size(a)%2) K += min(minA[a], m[a]);
	}

	void upd(int n, ll t) {
		n = rep(n);

		if(size(n)%2) K -= min(minA[n], m[n]);

		m[n] = min(m[n], t);
		if(size(n)%2) K += min(minA[n], m[n]);
	}
};

std::vector<long long> calculate_costs(vector<int> W, vector<int> A,  vector<int> B, vector<int> E) 
{
	int N = A.size();
	ll ansb = 0;

	for(int i=0; i<N; i++) A[i] -= B[i], ansb += B[i];

	vector<int> id(N);
	iota(all(id), 0);
	sort(all(id), [&](int &i, int &j){return W[i]<W[j];});

	vector<int> W2(N), A2(N);
	for(int i=0; i<N; i++) {
		W2[i] = W[id[i]];
		A2[i] = A[id[i]];
	}
	swap(W, W2);
	swap(A, A2);

	// all weigths sorted - much better!

	K = accumulate(all(A), 0LL);
	DSU dsu(W, A);

	int Q = E.size();
	id.resize(Q);
	iota(all(id), 0);
	sort(all(id), [&](int &i, int &j){return E[i]<E[j];});
	vector<ll> ans(Q, ansb);

	int ka = min(A[0], A[N-1]);
	for(int i=2; i<N-2; i++) ka = min(ka, A[i]);

	int k = ka;
	if(N > 1) k = min({k, A[1], A[N-2]});

	for(int i=0; i<Q; i++) {
		if(N%2 == 0);
		else if(N %2 == 0 || E[i] > 1) ans[i] += k;
		else ans[i] += ka;
	}
	return ans;

	vector<int> diff(N-1);
	iota(all(diff), 0);
	sort(all(diff), [&](int &i, int &j){return W[i+1]-W[i] > W[j+1]-W[j];});

	priority_queue<array<ll, 3>> pq;
	for(int i=1; i<N-1; i++) {
		pq.push( {-(W[i+1]-W[i-1]), i, A[i]});
	}

	for(auto &i: id) {
		ll q = E[i];

		while(!diff.empty() && W[diff.back()+1] - W[diff.back()] <= q) {
			dsu.join(diff.back(), diff.back()+1, W[diff.back()+1] - W[diff.back()]);
			diff.pop_back();
		}

		while(!pq.empty()) {
			auto [t, n, qt] = pq.top();
			t /= -1;
			if(t > q) break;
			pq.pop();

			dsu.upd(n, qt);
		}

		ans[i] += K;
	}

	return ans;
}


#ifdef MARCO
int main() {
  int N;
  assert(1 == scanf("%d", &N));
  std::vector<int> W(N), A(N), B(N);
  for (int i = 0; i < N; i++)
    assert(3 == scanf("%d%d%d", &W[i], &A[i], &B[i]));
  int Q;
  assert(1 == scanf("%d", &Q));
  std::vector<int> E(Q);
  for (int j = 0; j < Q; j++)
    assert(1 == scanf("%d", &E[j]));
  fclose(stdin);

  std::vector<long long> R = calculate_costs(W, A, B, E);

  int S = (int)R.size();
  for (int j = 0; j < S; j++)
    printf("%lld\n", R[j]);
  fclose(stdout);

  return 0;
}
#endif
#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...