// File C.cpp created on 01.12.2025 at 14:24:02
#include <bits/stdc++.h>
using i64 = long long;
#ifdef DEBUG
#include "/home/ahmetalp/Desktop/Workplace/debug.h"
#else
#define debug(...) void(23)
#endif
constexpr int md = int(1E9) + 7;
int add(int x, int y) {
x += y;
if (x >= md) {
x -= md;
}
return x;
}
int sub(int x, int y) {
x -= y;
if (x < 0) {
x += md;
}
return x;
}
int mul(int x, int y) {
return 1LL * x * y % md;
}
#define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1)
struct segtree {
struct node {
int siz = 1;
i64 act = 0;
int sum = 0;
i64 lz = 0;
node() {}
node(i64 x) : act(x), sum(x % md) {}
void modify(i64 x) {
act += x;
sum += mul(x % md, siz);
lz += x;
}
};
node unite(const node& lhs, const node& rhs) {
node res;
res.siz = lhs.siz + rhs.siz;
res.sum = add(lhs.sum, rhs.sum);
return res;
}
int n;
std::vector<node> tree;
segtree() {}
void init(int n_) {
n = n_;
tree.resize(n << 1);
auto dfs = [&](auto&& self, int v, int l, int r) -> void {
if (l == r) {
return;
}
def;
self(self, lv, l, mid);
self(self, rv, mid + 1, r);
tree[v] = unite(tree[lv], tree[rv]);
};
dfs(dfs, 0, 0, n - 1);
}
void push(int v, int l, int r) {
def;
tree[lv].modify(tree[v].lz);
tree[rv].modify(tree[v].lz);
tree[v].lz = 0;
}
void set(int v, int l, int r, int p, i64 x) {
if (l == r) {
tree[v] = x;
return;
}
def;
push(v, l, r);
if (p <= mid) {
set(lv, l, mid, p, x);
} else {
set(rv, mid + 1, r, p, x);
}
tree[v] = unite(tree[lv], tree[rv]);
}
void set(int p, i64 x) {
set(0, 0, n - 1, p, x);
}
void modify(int v, int l, int r, int ql, int qr, i64 x) {
if (ql == l && r == qr) {
tree[v].modify(x);
return;
}
def;
push(v, l, r);
if (qr <= mid) {
modify(lv, l, mid, ql, qr, x);
} else if (mid + 1 <= ql) {
modify(rv, mid + 1, r, ql, qr, x);
} else {
modify(lv, l, mid, ql, mid, x);
modify(rv, mid + 1, r, mid + 1, qr, x);
}
tree[v] = unite(tree[lv], tree[rv]);
}
void modify(int l, int r, i64 x) {
modify(0, 0, n - 1, l, r, x);
}
i64 get(int v, int l, int r, int p) {
if (l == r) {
return tree[v].act;
}
def;
push(v, l, r);
if (p <= mid) {
return get(lv, l, mid, p);
} else {
return get(rv, mid + 1, r, p);
}
}
i64 get(int p) {
return get(0, 0, n - 1, p);
}
int sum() {
return tree[0].sum;
}
} seg;
int N;
std::vector<int> par;
std::vector<i64> dis;
std::vector<std::vector<int>> adj;
std::vector<i64> mx2;
std::vector<int> heavy;
std::vector<int> siz;
std::vector<int> top;
std::vector<int> tin;
std::vector<int> tout;
std::vector<int> tour;
int tim;
void dfs1(int v) {
siz[v] = 1;
for (auto& u : adj[v]) {
heavy[v] = u;
dfs1(u);
siz[v] += siz[u];
if (siz[u] > siz[adj[v][0]]) {
std::swap(u, adj[v][0]);
}
}
}
void dfs2(int v) {
tour[tim] = v;
tin[v] = tim++;
for (auto u : adj[v]) {
top[u] = (u == adj[v][0] ? top[v] : u);
dfs2(u);
}
tout[v] = tim;
}
void init() {
dfs1(0);
dfs2(0);
}
i64 ans = 0;
void upd(int v, i64 x) {
while (v != 0) {
int u = par[v];
if (heavy[u] == v) {
seg.modify(tin[u], tin[u], x);
} else {
i64 dv = seg.get(tin[v]);
i64 du = seg.get(tin[u]);
if (dv + dis[v] > du) {
ans -= mx2[u];
mx2[u] = du;
ans += mx2[u];
seg.set(tin[u], dv + dis[v]);
x = dv + dis[v] - du;
heavy[u] = v;
} else if (dv + dis[v] > mx2[u]) {
ans -= mx2[u];
mx2[u] = dv + dis[v];
ans += mx2[u];
break;
} else {
break;
}
}
v = u;
}
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cin >> N;
par.resize(N);
dis.resize(N);
adj.resize(N);
seg.init(N);
mx2.resize(N);
heavy.resize(N);
top.resize(N);
siz.resize(N);
tin.resize(N);
tout.resize(N);
tour.resize(N);
for (int i = 1; i < N; ++i) {
std::cin >> par[i];
adj[par[i]].emplace_back(i);
}
init();
for (int i = 1; i < N; ++i) {
std::cin >> dis[i];
upd(i, dis[i]);
}
std::cout << add(ans % md, seg.sum()) << '\n';
int Q;
std::cin >> Q;
while (Q--) {
int v, x;
std::cin >> v >> x;
dis[v] += x;
upd(v, x);
std::cout << add(ans % md, seg.sum()) << '\n';
#ifdef LOCAL
debug(mx2);
#endif
}
return 0;
}
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |
| # | Verdict | Execution time | Memory | Grader output |
|---|
| Fetching results... |