제출 #130242

#제출 시각아이디문제언어결과실행 시간메모리
130242darkkcyanConstruction of Highway (JOI18_construction)C++14
100 / 100
542 ms113520 KiB
#include <bits/stdc++.h> using namespace std; using namespace std::placeholders; #define llong long long #define xx first #define yy second #define len(x) ((int)x.size()) #define rep(i,n) for (int i = -1; ++ i < n; ) #define rep1(i,n) for (int i = 0; i ++ < n; ) #define all(x) x.begin(), x.end() // #define rand __rand // mt19937 rand(chrono::system_clock::now().time_since_epoch().count()); // or mt19937_64 #define maxn 101010 int n; int c[maxn]; vector<int> gr[maxn]; int parent[maxn]; int query[maxn]; int subtree_size[maxn]; shared_ptr<int> chain_head[maxn]; int chain_id[maxn]; void build_hld(int u) { subtree_size[u] = 1; for (auto v: gr[u]) { build_hld(v); subtree_size[u] += subtree_size[v]; if (!chain_head[u] or subtree_size[*chain_head[u]] < subtree_size[*chain_head[v]]) chain_head[u] = chain_head[v]; } if (!chain_head[u]) chain_head[u].reset(new int()); chain_id[u] = chain_id[*chain_head[u]] + 1; *chain_head[u] = u; } deque<pair<int, int>> chain_data[maxn]; vector<pair<int, int>> do_operation(int u, int liveliness) { if (u == 0) return {}; int head = *chain_head[u]; auto ans = do_operation(parent[head], liveliness); int n_remove = chain_id[head] - chain_id[u] + 1; int s = n_remove; while (s > 0 and chain_data[head].size()) { // check the size just for safety. int n_removing = min(s, chain_data[head].front().yy); s -= n_removing; chain_data[head].front().yy -= n_removing; ans.emplace_back(chain_data[head].front().xx, n_removing); if (chain_data[head].front().yy == 0) chain_data[head].pop_front(); } if (s > 0) { assert(false); } chain_data[head].emplace_front(liveliness, n_remove); return move(ans); } struct Bit { vector<llong> data; Bit(int size) : data(size + 10) {} void upd(int i, llong val) { for (++i; i < len(data); i += i & -i) data[i] += val; } llong get(int i) { llong ans = 0; for (++i; i > 0; i -= i & -i) ans += data[i]; return ans; } }; llong compute_cost(const vector<pair<int, int>>& chain) { vector<int> vals; for (auto i: chain) vals.push_back(i.xx); sort(vals.begin(), vals.end()); vals.resize(unique(vals.begin(), vals.end()) - vals.begin()); llong ans = 0; Bit bit(len(vals)); for (int i = len(chain); i--; ) { int cur_val = (int)(lower_bound(vals.begin(), vals.end(), chain[i].xx) - vals.begin()); llong cur_ans = 1ll * chain[i].yy * bit.get(cur_val - 1); ans += cur_ans; bit.upd(cur_val, chain[i].yy); } return ans; } int main(void) { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> n; rep1(i, n) cin >> c[i]; parent[1] = 0; rep(i, n - 1) { int p, u; cin >> p >> u; query[i] = u; parent[u] = p; gr[p].push_back(u); } build_hld(1); chain_data[1].emplace_back(c[1], 1); rep(i, n - 1) { int u = query[i]; cout << compute_cost(do_operation(parent[u], c[u])) << '\n'; int head = *chain_head[u]; if (head == u) { chain_data[head].emplace_front(c[u], 1); } else { assert(len(chain_data[head]) == 1); chain_data[head].front().yy ++; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...