제출 #529126

#제출 시각아이디문제언어결과실행 시간메모리
529126fhvirusConstruction of Highway (JOI18_construction)C++17
100 / 100
214 ms20804 KiB
// Knapsack DP is harder than FFT.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll; typedef pair<int,int> pii;
#define ff first
#define ss second
#define pb emplace_back
#define AI(x) begin(x),end(x)
#ifdef OWO
#define debug(args...) SDF(#args, args)
#define OIU(args...) ostream& operator<<(ostream&O,args)
#define LKJ(S,B,E,F) template<class...T>OIU(S<T...>s){O<<B;int c=0;for(auto i:s)O<<(c++?", ":"")<<F;return O<<E;}
LKJ(vector,'[',']',i)LKJ(deque,'[',']',i)LKJ(set,'{','}',i)LKJ(multiset,'{','}',i)LKJ(unordered_set,'{','}',i)LKJ(map,'{','}',i.ff<<':'<<i.ss)LKJ(unordered_map,'{','}',i.ff<<':'<<i.ss)
template<class...T>void SDF(const char* s,T...a){int c=sizeof...(T);if(!c){cerr<<"\033[1;32mvoid\033[0m\n";return;}(cerr<<"\033[1;32m("<<s<<") = (",...,(cerr<<a<<(--c?", ":")\033[0m\n")));}
template<class T,size_t N>OIU(array<T,N>a){return O<<vector<T>(AI(a));}template<class...T>OIU(pair<T...>p){return O<<'('<<p.ff<<','<<p.ss<<')';}template<class...T>OIU(tuple<T...>t){return O<<'(',apply([&O](T...s){int c=0;(...,(O<<(c++?", ":"")<<s));},t),O<<')';}
#else
#define debug(...) ((void)0)
#endif

struct LISAN : vector<int> {
	void done() { sort(AI()); erase(unique(AI()), end()); }
	int operator () (const int& v) const { return lower_bound(AI(), v) - begin(); }
};
struct BIT {
	int n; vector<int> val;
	BIT(int _n = 0): n(_n), val(n + 1, 0) {}
	void modify(int p, int v) {
		for (; p <= n; p += p & -p)
			val[p] += v;
	}
	int query(int p) {
		int r = 0;
		for (; p > 0; p -= p & -p)
			r += val[p];
		return r;
	}
};

const int kN = 100'001;
int N, C[kN], A[kN], B[kN];
int par[kN];
vector<int> chi[kN];

int dep[kN], siz[kN];
void dfs_siz(int u) {
	siz[u] = 1;
	for (int& v: chi[u]) {
		dep[v] = dep[u] + 1;
		dfs_siz(v);
		siz[u] += siz[v];
		if (siz[v] > siz[chi[u][0]])
			swap(v, chi[u][0]);
	}
}
vector<pii> chain[kN];
int head[kN];
void dfs_head(int u, int h) {
	head[u] = h;
	for (const int& v: chi[u])
		dfs_head(v, v == chi[u][0] ? h : v);
	if (chain[h].empty())
		chain[h].pb(-1, dep[u] + 1);
	if (chain[h].back().ff != C[u])
		chain[h].pb(C[u], dep[u]);
	else
		chain[h].back().ss = dep[u];
}

signed main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	cin >> N;
	LISAN lisan;
	for (int i = 1; i <= N; ++i) {
		cin >> C[i];
		lisan.pb(C[i]);
	}
	lisan.done();
	for (int i = 1; i <= N; ++i)
		C[i] = lisan(C[i]) + 1;
	for (int i = 1; i < N; ++i) {
		cin >> A[i] >> B[i];
		par[B[i]] = A[i];
		chi[A[i]].pb(B[i]);
	}

	dfs_siz(1);
	dfs_head(1, 1);

	BIT bit(lisan.size());
	vector<pii> vals, tmp;
	for (int i = 1; i < N; ++i) {
		int u = A[i];
		do {
			int h = head[u];
			while (8e7 /* is stronger than me */ ) {
				pii cur = chain[h].back();
				if (cur.ss > dep[u]) break;
				chain[h].pop_back();
				if (chain[h].back().ss > dep[u]) {
					tmp.pb(cur.ff, dep[u] - cur.ss + 1);
					if (chain[h].back().ss > dep[u] + 1)
						chain[h].pb(cur.ff, dep[u] + 1);
					break;
				}
				tmp.pb(cur.ff, chain[h].back().ss - cur.ss);
			}
			while (!tmp.empty()) {
				vals.push_back(tmp.back());
				tmp.pop_back();
			}
			u = par[h];
		} while (u != 0);

		ll ans = 0;
		for (const auto& [val, num]: vals) {
			ans += 1ll * bit.query(val - 1) * num;
			bit.modify(val, num);
		}
		cout << ans << '\n';
		for (const auto& [val, num]: vals)
			bit.modify(val, -num);
		vals.clear();

		u = A[i];
		do {
			int h = head[u];
			chain[h].pb(C[B[i]], dep[h]);
			u = par[h];
		} while (u != 0);
	}
	
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...