Submission #372973

#TimeUsernameProblemLanguageResultExecution timeMemory
372973atoizConstruction of Highway (JOI18_construction)C++14
100 / 100
275 ms5608 KiB
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <map>
#include <vector>

using namespace std;

const int MAXN = 100007;
int N, par[MAXN], ch[MAXN][2], dep[MAXN], val[MAXN], ft[MAXN];

bool isRoot(int u) { return u != ch[par[u]][0] && u != ch[par[u]][1]; }
bool dir(int u) { return u == ch[par[u]][1]; }
void rot(int u) {
	int p = par[u], g = par[p], k = dir(u);
	if (!isRoot(p)) ch[g][dir(p)] = u;
	par[u] = g;
	par[ch[p][k] = ch[u][!k]] = p;
	par[ch[u][!k] = p] = u;
}
void splay(int u) {
	for (; !isRoot(u); rot(u)) {
		if (!isRoot(par[u])) rot(dir(u) == dir(par[u]) ? par[u] : u);
	}
}
int64_t access(int u) {
	vector<tuple<int, int, int>> segs;
	for (int v = 0; u; v = u, u = par[v]) {
		splay(u);
		
		int x = ch[u][1];
		ch[u][1] = v;

		while (ch[u][0]) u = ch[u][0];
		splay(u);

		if (x) {
			while (ch[x][0]) x = ch[x][0];
			splay(x);
			val[x] = val[u];
		}

		if (v) { // ignore first segment ({B_j})
			segs.emplace_back(val[u], dep[u] + 1, dep[v] - dep[u]);
		}
	}

	int64_t cost = 0;
	sort(segs.begin(), segs.end());
	reverse(segs.begin(), segs.end());
	for (auto tmp : segs) {
		int p, x;
		tie(ignore, p, x) = tmp;
		for (int i = p; i > 0; i -= i & (-i)) cost += (int64_t) ft[i] * x;
		for (int i = p; i <= N; i += i & (-i)) ft[i] += x;
	}

	for (auto tmp : segs) {
		int p, x;
		tie(ignore, p, x) = tmp;
		for (int i = p; i <= N; i += i & (-i)) ft[i] -= x;
	}

	return cost;
}

int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> N;
	for (int u = 1; u <= N; ++u) {
		cin >> val[u];
	}
	for (int i = 0; i < N - 1; ++i) {
		int u, v;
		cin >> u >> v;
		dep[v] = dep[u] + 1, par[v] = u;
		cout << access(v) << '\n';
		val[1] = val[v];
	}
}


#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...