Submission #1351469

#TimeUsernameProblemLanguageResultExecution timeMemory
1351469marcogambaroNile (IOI24_nile)C++20
38 / 100
42 ms11944 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;
priority_queue<pll> pq;

struct DSU {
	vector<ll> dsu, minA, intL, intR, L, R, dm;

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

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

		if(intR[a] != -1) {
			pq.emplace(-t-intR[a], a);
		}
		intR[a] = t;
		if(intL[a] == -1) intL[a] = t;

		if(intL[b] != -1) {
			pq.emplace(-t-intL[b], b);
		}
		intL[b] = t;
		if(intR[b] == -1) intR[b] = t;

		minA[a] = min(minA[a], minA[b]);
		dm[a] &= dm[b];

		dsu[a] += dsu[b];
		dsu[b] = a;
		intR[a] = intR[b];		
		if(size(a)%2 && dm[a]) K += minA[a];
	}

	void make0(int n) {
		n = rep(n);
		if(dm[n] && size(n)%2) K -= minA[n];
		dm[n] = 0;
	}
};

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];});

	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] = pq.top();
		// 	t /= -1;
		// 	if(t > q) break;
		// 	pq.pop();

		// 	dsu.make0(n);
		// }

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