結果
問題 | No.386 貪欲な領主 |
ユーザー | rpy3cpp |
提出日時 | 2017-10-11 02:21:25 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 299 ms / 2,000 ms |
コード長 | 4,607 bytes |
コンパイル時間 | 2,509 ms |
コンパイル使用メモリ | 182,696 KB |
実行使用メモリ | 39,224 KB |
最終ジャッジ日時 | 2024-11-17 08:49:15 |
合計ジャッジ時間 | 4,837 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 2 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 299 ms
39,224 KB |
testcase_05 | AC | 272 ms
31,452 KB |
testcase_06 | AC | 279 ms
31,360 KB |
testcase_07 | AC | 4 ms
5,248 KB |
testcase_08 | AC | 33 ms
6,016 KB |
testcase_09 | AC | 6 ms
5,248 KB |
testcase_10 | AC | 2 ms
5,248 KB |
testcase_11 | AC | 2 ms
5,248 KB |
testcase_12 | AC | 3 ms
5,248 KB |
testcase_13 | AC | 9 ms
5,248 KB |
testcase_14 | AC | 279 ms
31,376 KB |
testcase_15 | AC | 258 ms
38,964 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using vi = vector<int>; using vvi = vector<vector<int>>; class RMQidx{ private: int n; // size of val vector<vector<int>> idx; // doubling range min index. idx[k][p]: index of min(val[p:p+2^k]) including p and not including p+2^k. vector<int> val; void init(const vector<int> &src){ n = src.size(); val = src; idx.emplace_back(vector<int>(n, 0)); for (int i = 0; i != n; ++i) idx[0][i] = i; for (int k = 0, r = 1; r < n; ++k, r <<= 1){ idx.emplace_back(idx[k]); for (int p = 0; p + r < n; ++p){ auto idxL = idx[k][p]; auto idxR = idx[k][p + r]; idx[k + 1][p] = (val[idxL] > val[idxR]) ? idxR : idxL; } } } public: RMQidx(): n(0), idx(vector<vector<int>>()), val(vector<int>()) {} RMQidx(const vector<int> &src){init(src);} int query(int L, int R){ // index of min(data[0][L..R] including both ends. [L, R] assert(L <= R); if (L == R) return L; int k = 31 - __builtin_clz(R - L); auto idxL = idx[k][L]; auto idxR = idx[k][R + 1 - (1 << k)]; return (val[idxL] > val[idxR])? idxR: idxL; } }; class LCA{ private: int n; // number of vertexes int root; const vector<vector<int>> & Es; vector<int> height; // height[v] = height of vertex v. vector<int> i2v; // i2v[i] = v. Euler tour order of vertexes. vector<int> v2i; // v2i[v] = i. Last position of vertex v in the Euler tour. RMQidx rmq; // Range Minimum Query object which returns the position (idx) of the minimum value in the euler tour. void dfs(int v, int h){ height[v] = h; i2v.push_back(v); for (auto u : Es[v]){ if (height[u] == -1) { dfs(u, h + 1); i2v.push_back(v); } } } public: LCA(const vector<vector<int>> &_Es, int _root = 0):Es(_Es){ n = Es.size(); root = _root; height = vector<int>(n, -1); v2i = vector<int>(n, -1); dfs(root, 0); assert(i2v.size() == 2 * n - 1); vector<int> val(2 * n - 1); for (int i = 0; i != 2 * n - 1; ++i) { val[i] = height[i2v[i]]; v2i[i2v[i]] = i; } rmq = RMQidx(val); } int query(int u, int v){ // returns lowest common ancestor of vertex u and vertex v. int i = v2i[u]; int j = v2i[v]; if (i > j) swap(i, j); return i2v[rmq.query(i, j)]; } int dist(int u, int v){ // returns the distance between vertex u and vertex v. int k = query(u, v); return height[u] + height[v] - 2 * height[k]; } }; void dfs_et(int v, int p, vi & euler_tour, const vvi & Es){ // v: current vertex, p: parent of v euler_tour.push_back(v); for (auto u : Es[v]){ if (u == p) continue; dfs_et(u, v, euler_tour, Es); euler_tour.push_back(v); } } vi get_euler_tour(const vvi &Es, int root = 0){ vi euler_tour; int nV = Es.size(); dfs_et(root, -1, euler_tour, Es); return euler_tour; } vi get_first_pos(const vi & et, int N){ vi first(N, -1); for (int i = 0; i < et.size(); ++i){ if (first[et[i]] == -1) first[et[i]] = i; } return first; } vi get_last_pos(const vi & et, int N){ vi last(N, -1); for (int i = 0; i < et.size(); ++i){ last[et[i]] = i; } return last; } int main() { int N; cin >> N; vector<vector<int>> Es(N); for (int i = 1; i < N; ++i){ int a, b; cin >> a >> b; Es[a].push_back(b); Es[b].push_back(a); } LCA lca(Es); vi Us(N); for (auto & u : Us) cin >> u; auto euler_tour = get_euler_tour(Es); auto first = get_first_pos(euler_tour, N); auto last = get_last_pos(euler_tour, N); vector<long long> imos(2*N - 1, 0); int M; cin >> M; while (M--){ int a, b, c; cin >> a >> b >> c; int d = lca.query(a, b); imos[first[a]] += c; imos[first[b]] += c; if (d != 0) imos[first[d] - 1] -= c; imos[first[d]] -= c; } vector<long long> cum(2 * N - 1, 0); cum[0] = imos[0]; for (int i = 1; i < cum.size(); ++i){ cum[i] = cum[i - 1] + imos[i]; } long long cost = 0; cost += Us[0] * cum[last[0]]; for (int i = 1; i < N; ++i){ cost += Us[i] * (cum[last[i]] - cum[first[i] - 1]); } cout << cost; return 0; }