제출 #1261897

#제출 시각아이디문제언어결과실행 시간메모리
1261897minggaConstruction of Highway (JOI18_construction)C++20
100 / 100
164 ms19388 KiB
// Author: caption_mingle
#include "bits/stdc++.h"

using namespace std;

#define ln "\n"
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define ll long long
const int mod = 1e9 + 7;
const int inf = 2e9;
const int N = 1e5 + 7;
int n, par[N], h[N], heavy[N], sz[N], nxt[N], a[N];
vector<int> g[N];
vector<pair<int, int>> que;
vector<pair<int, int>> chain[N];

struct BIT {
	vector<ll> bit;
	int n;
	BIT() {}
	BIT(int n) : n(n) {
		bit.resize(n + 1, 0);
	}
	void update(int u, int x) {
		for(; u <= n; u += (u & -u)) bit[u] += x;
	}
	ll get(int u) {
		ll ans = 0;
		for(; u > 0; u -= (u & -u)) ans += bit[u];
		return ans;
	}
};



void dfs(int u) {
	sz[u] = 1;
	for(int v : g[u]) {
		h[v] = h[u] + 1;
		par[v] = u;
		dfs(v);
		sz[u] += sz[v];
		if(sz[v] > sz[heavy[u]]) heavy[u] = v;
	}
}

void hld(int u) {
	for(int v : g[u]) {
		nxt[v] = (v == heavy[u] ? nxt[u] : v);
		hld(v);
	}
}

ll query(int u) {
	vector<pair<int, int>> dak;
	vector<int> val;
	while(u) {
		int pu = nxt[u];
		int mx = h[u] - h[pu] + 1;
		vector<pair<int, int>> tmp;
		for(int i = sz(chain[pu]) - 1; i >= 0; i--) {
			val.pb(chain[pu][i].fi);
			// cerr << chain[pu][i].fi << ' ' << chain[pu][i].se << ln;
			if(chain[pu][i].se <= mx) {
				mx -= chain[pu][i].se;
				tmp.pb(chain[pu][i]);
			} else {
				tmp.pb({chain[pu][i].fi, mx});
				break;
			}
		}
		// cerr << u << ' ' << pu << ' ' << par[pu] << ln;
		u = par[pu];
		for(int i = sz(tmp) - 1; i >= 0; i--) dak.pb(tmp[i]);
	}
	sort(all(val));
	val.erase(unique(all(val)), val.end());
	BIT bit(sz(val));
	ll ans = 0;
	for(auto [num, cnt] : dak) {
		// cerr << num << ' ' << cnt << ln;
		num = upper_bound(all(val), num) - val.begin();
		ans += bit.get(num - 1) * cnt;
		bit.update(num, cnt);
	}
	return ans;
}

void update(int u, int col) {
	while(u) {
		int pu = nxt[u];
		int mx = h[u] - h[pu] + 1;
		while(sz(chain[pu])) {
			if(chain[pu].back().se <= mx) {
				mx -= chain[pu].back().se;
				chain[pu].pop_back();
			} else {
				chain[pu].back().se -= mx;
				break;
			}
		}
		chain[pu].pb({col, h[u] - h[pu] + 1});
		// cerr << "CHAIN " << pu << ln;
		// for(auto [v, cnt] : chain[pu]) cerr << v << ' ' << cnt << ln;
		u = par[pu];
	}
}

signed main() {
	cin.tie(0) -> sync_with_stdio(0);
	#define task ""
	if(fopen(task ".INP", "r")) {
		freopen(task ".INP", "r", stdin);
		freopen(task ".OUT", "w", stdout);
	}
	cin >> n;
	for(int i = 1; i <= n; i++) cin >> a[i];
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		que.pb({u, v});
		g[u].pb(v);
	}
	nxt[1] = 1;
	dfs(1);
	hld(1);
	chain[1].pb({a[1], 1});
	for(auto [u, v] : que) {
		cout << query(u) << ln;
		update(v, a[v]);
	}
    cerr << "\nTime: " << clock() * 1000 / CLOCKS_PER_SEC;
}

컴파일 시 표준 에러 (stderr) 메시지

construction.cpp: In function 'int main()':
construction.cpp:117:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  117 |                 freopen(task ".INP", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
construction.cpp:118:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  118 |                 freopen(task ".OUT", "w", stdout);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...