Submission #119920

#TimeUsernameProblemLanguageResultExecution timeMemory
119920arman_ferdousConstruction of Highway (JOI18_construction)C++14
100 / 100
589 ms95340 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const int N = 1e5+100;
int n, c[N];
vector<int> g[N];
struct edge{
	int u, v;
}e[N];

int par[N], sub[N], lev[N];
int subdfs(int u, int f, int l) {
	par[u] = f;
	sub[u] = 1;
	lev[u] = l;
	for(int v : g[u]) if(v != f) 
		sub[u] += subdfs(v, u, l + 1);
	return sub[u];
}

int head[N], cid[N], zap;
deque< pair<int,ll> > val[N];
void hld(int u, int f, int dad, int id) {
	head[u] = dad;
	cid[u] = id;

	if(!val[id].empty() && val[id].back().first == c[u])
		val[id].back().second++;
	else val[id].push_back({c[u], 1});

	int mx = -1, sc;
	for(int v : g[u]) if(v != f && sub[v] > mx)
		mx = sub[v], sc = v;
	if(mx == -1) return;
	hld(sc, u, dad, id);

	for(int v : g[u]) if(v != f && v != sc)
		hld(v, u, v, ++zap);
}

int bit[N];
deque< pair<int,ll> > tmp, full;

void upd(int pos, int x) {
	while(pos < N) bit[pos] += x, pos += pos&-pos;
}
ll get(int pos, int sum = 0) {
	while(pos > 0) sum += bit[pos], pos -= pos&-pos;
	return sum;
}

ll calc(int u, int newc) {
	full.clear();
	while(u != -1) {
		tmp.clear();
		int take = lev[u] - lev[head[u]] + 1, id = cid[u];
		while(take) {
			if(take - val[id][0].second <= 0) {
				tmp.push_front({val[id][0].first, take});
				val[id][0].second -= take;
				if(val[id][0].second == 0) val[id].pop_front();
				break;
			}
			else {
				tmp.push_front(val[id][0]);
				take -= val[id][0].second;
				val[id].pop_front();
			}
		}
		if(!val[id].empty() && val[id][0].first == newc) 
			val[id][0].second += lev[u] - lev[head[u]] + 1;
		else val[id].push_front({newc, lev[u] - lev[head[u]] + 1});
		u = par[head[u]];
		while(!tmp.empty()) {
			full.push_front(tmp.front());
			tmp.pop_front();
		}
	}
	int sz = full.size(); ll ret = 0;
	for(int i = sz - 1; i >= 0; i--) {
		ret += get(full[i].first - 1) * full[i].second;
		upd(full[i].first, full[i].second);
	}
	for(int i = 0; i < sz; i++) 
		upd(full[i].first, -full[i].second);
	return ret;
}

vector<int> v;
map<int,int> mp;
int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &c[i]);
		v.push_back(c[i]);
	} sort(v.begin(), v.end());
	v.erase(unique(v.begin(),v.end()),v.end());
	int cur = 1;
	for(auto it : v) mp[it] = cur++;
	for(int i = 1; i <= n; i++) c[i] = mp[c[i]];

	for(int i = 1; i < n; i++) {
		scanf("%d %d", &e[i].u, &e[i].v);
		g[e[i].u].push_back(e[i].v);
		g[e[i].v].push_back(e[i].u);
	}
	subdfs(1, -1, 1);
	hld(1, -1, 1, ++zap);

	for(int i = 1; i < n; i++)
		printf("%lld\n", calc(e[i].u, c[e[i].v]));
	return 0;
}

Compilation message (stderr)

construction.cpp: In function 'int main()':
construction.cpp:93:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d", &n);
  ~~~~~^~~~~~~~~~
construction.cpp:95:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d", &c[i]);
   ~~~~~^~~~~~~~~~~~~
construction.cpp:104:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d", &e[i].u, &e[i].v);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...