Submission #1351497

#TimeUsernameProblemLanguageResultExecution timeMemory
1351497marcogambaroNile (IOI24_nile)C++20
0 / 100
28 ms10924 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;

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

	DSU(vector<int> &v, vector<int> &a) {
		int N = v.size();
		dsu = vector<ll>(N, -1);
		minA = L = R = vector<ll>(N);
		for(int i=0; i<N; i++) minA[i] = a[i];
		ogA = a;
	}

	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 -= minA[a];
		if(size(b)%2) K -= minA[b];

		if(size(a) == 1 && size(b) == 1) {
			L[a] = ogA[b];
			R[a] = ogA[a];
			minA[a] = 1e17;
		}
		else if(size(b) == 1) {
			minA[a] = min({minA[a], minA[b], R[a]});
			R[a] = ogA[b-1];
		}
		else {
			L[a] = ogA[a+1];
			minA[a] = min({minA[a], minA[b], L[b], R[a]});
			R[a] = R[b];
		}		

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

		if(size(a)%2) K += minA[a];
	}

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

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

		minA[n] = min(minA[n], t);
		if(size(n)%2) K += minA[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);

	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, min(W[i+1]-W[i], W[i]-W[i-1])});
	}

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