結果
| 問題 |
No.899 γatheree
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-10-05 06:05:41 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.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 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 23 |
ソースコード
#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';
}
}