結果
問題 | No.899 γatheree |
ユーザー | pekempey |
提出日時 | 2019-10-05 06:05:41 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 739 ms / 2,000 ms |
コード長 | 4,178 bytes |
コンパイル時間 | 2,578 ms |
コンパイル使用メモリ | 193,416 KB |
実行使用メモリ | 18,792 KB |
最終ジャッジ日時 | 2024-10-04 17:44:51 |
合計ジャッジ時間 | 16,287 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,816 KB |
testcase_02 | AC | 2 ms
6,816 KB |
testcase_03 | AC | 2 ms
6,816 KB |
testcase_04 | AC | 2 ms
6,816 KB |
testcase_05 | AC | 3 ms
6,820 KB |
testcase_06 | AC | 691 ms
18,600 KB |
testcase_07 | AC | 678 ms
18,496 KB |
testcase_08 | AC | 688 ms
18,572 KB |
testcase_09 | AC | 697 ms
18,544 KB |
testcase_10 | AC | 690 ms
18,512 KB |
testcase_11 | AC | 665 ms
18,504 KB |
testcase_12 | AC | 676 ms
18,504 KB |
testcase_13 | AC | 672 ms
18,568 KB |
testcase_14 | AC | 693 ms
18,480 KB |
testcase_15 | AC | 662 ms
18,504 KB |
testcase_16 | AC | 671 ms
18,524 KB |
testcase_17 | AC | 680 ms
18,468 KB |
testcase_18 | AC | 683 ms
18,500 KB |
testcase_19 | AC | 683 ms
18,612 KB |
testcase_20 | AC | 739 ms
18,472 KB |
testcase_21 | AC | 603 ms
18,696 KB |
testcase_22 | AC | 556 ms
18,792 KB |
testcase_23 | AC | 571 ms
18,752 KB |
ソースコード
#include <bits/stdc++.h> #define rep(i, n) for (int i = 0; i < (n); i++) #define repr(i, n) for (int i = (n) - 1; i >= 0; i--) #define rep2(i, l, r) for (int i = (l); i < (r); i++) #define rep2r(i, l, r) for (int i = (r) - 1; i >= (l); i--) #define range(a) a.begin(), a.end() using namespace std; using ll = long long; template<class Vec, class Mat, class VV, class MV, class MM> struct lazy_segtree { int N; vector<Vec> vec; vector<Mat> mat; Vec vec_ident; Mat mat_ident; VV vec_vec; MV mat_vec; MM mat_mat; lazy_segtree( int n, function<Vec(int)> init, Vec vec_ident_, Mat mat_ident_, VV vec_vec_, MV mat_vec_, MM mat_mat_) : vec_ident(vec_ident_), mat_ident(mat_ident_), vec_vec(vec_vec_), mat_vec(mat_vec_), mat_mat(mat_mat_) { N = 1; while (N < n) N *= 2; vec.resize(N * 2, vec_ident); mat.resize(N * 2, mat_ident); for (int i = 0; i < n; i++) { vec[i + N] = init(i); } for (int i = N - 1; i >= 1; i--) { pull(i); } } void apply(int k, Mat v) { mat[k] = mat_mat(v, mat[k]); vec[k] = mat_vec(v, vec[k]); } void push(int k) { apply(k << 1 | 0, mat[k]); apply(k << 1 | 1, mat[k]); mat[k] = mat_ident; } void pull(int k) { vec[k] = vec_vec(vec[k << 1], vec[k << 1 | 1]); } void update(int a, int b, Mat v, int k, int l, int r) { if (r <= a || b <= l) return; if (a <= l && r <= b) { apply(k, v); return; } push(k); update(a, b, v, k << 1 | 0, l, l + r >> 1); update(a, b, v, k << 1 | 1, l + r >> 1, r); pull(k); } void update(int a, int b, Mat v) { update(a, b, v, 1, 0, N); } Vec query(int a, int b, int k, int l, int r) { if (r <= a || b <= l) return vec_ident; if (a <= l && r <= b) return vec[k]; push(k); Vec vl = query(a, b, k << 1 | 0, l, l + r >> 1); Vec vr = query(a, b, k << 1 | 1, l + r >> 1, r); return vec_vec(vl, vr); } Vec query(int a, int b) { return query(a, b, 1, 0, N); } }; template<class Vec, class Mat, class VV, class MV, class MM> lazy_segtree<Vec, Mat, VV, MV, MM> create_lazy_segtree( int n, function<Vec(int)> init, Vec vec_ident_, Mat mat_ident_, VV vec_vec_, MV mat_vec_, MM mat_mat_) { return lazy_segtree<Vec, Mat, VV, MV, MM>(n, init, vec_ident_, mat_ident_, vec_vec_, mat_vec_, mat_mat_); } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); int N; cin >> N; vector<vector<int>> G(N); rep(i, N - 1) { int a, b; cin >> a >> b; G[a].push_back(b); G[b].push_back(a); } int k = 0; vector<int> par(N, -1); vector<int> L(N); vector<int> R(N); vector<int> L2(N, 1e9); vector<int> R2(N, -1e9); vector<int> label(N); vector<int> label_inv(N); queue<int> q; q.push(0); while (!q.empty()) { int u = q.front(); q.pop(); L[u] = k + 1; for (int v : G[u]) if (v != par[u]) { label[v] = ++k; label_inv[label[v]] = v; par[v] = u; q.push(v); } R[u] = k + 1; } rep(u, N) for (int v : G[u]) if (v != par[u]) { L2[u] = min(L2[u], L[v]); R2[u] = max(R2[u], R[v]); }; vector<ll> A(N); rep(i, N) cin >> A[i]; auto seg = create_lazy_segtree<pair<ll, ll>, ll>( N, [&](int i) { return make_pair(A[label_inv[i]], 1); }, make_pair(0, 0), -1, [](pair<ll, ll> a, pair<ll, ll> b) { return make_pair(a.first + b.first, a.second + b.second); }, [](ll a, pair<ll, ll> b) { return a == -1 ? b : make_pair(a * b.second, b.second); }, [](ll a, ll b) { return a != -1 ? a : b; } ); int Q; cin >> Q; while (Q--) { int x; cin >> x; ll s = 0; auto f = [&](int l, int r) { if (l <= r) { s += seg.query(l, r).first; seg.update(l, r, 0); } }; f(L[x], R[x]); f(L2[x], R2[x]); if (par[x] != -1) { int p = par[x]; f(label[p], label[p] + 1); f(L[p], R[p]); if (par[p] != -1) { int pp = par[p]; f(label[pp], label[pp] + 1); } } f(label[x], label[x] + 1); seg.update(label[x], label[x] + 1, s); cout << s << '\n'; } }