#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair <int, int>
#define fi first
#define se second
#define mp make_pair
const int NM = 1e5, LOG = 16, MOD = 1e9+7;
struct node{
int sz, f, g;
};
struct tag{
pii f, g;
tag(){
f = g = mp(1, 0);
}
tag(pii y, pii z){
f = y, g = z;
}
};
int n, q, p[NM+5], d[NM+5], dep[NM+5], sumd[NM+5], sz[NM+5], f[NM+5], g[NM+5], jump[NM+5][LOG+5], cur = 0;
vector <int> son[NM+5];
int head[NM+5], timer = 0, tin[NM+5], tour[NM+5], tout[NM+5];
node st[4*NM+5];
tag lazy[4*NM+5];
void dfs_sz(int u){
dep[u] = (u == 1 ? 0 : dep[p[u]]+1);
sumd[u] = sumd[p[u]]+d[u];
sz[u] = 1;
f[u] = g[u] = 0;
for (int v : son[u]){
dfs_sz(v);
sz[u] += sz[v];
if (f[v]+d[v] > f[u]){
g[u] = f[u];
f[u] = f[v]+d[v];
}
else if (f[v]+d[v] > g[u]){
g[u] = f[v]+d[v];
}
}
cur += 2*sumd[u];
}
void build_sparse(){
for (int i = 1; i <= n; i++) jump[i][0] = p[i];
for (int j = 1; j <= LOG; j++)
for (int i = 1; i <= n; i++)
jump[i][j] = jump[jump[i][j-1]][j-1];
}
void dfs_hld(int u){
tin[u] = ++timer;
tour[timer] = u;
int mxVtx = -1;
for (int v : son[u]){
if (mxVtx == -1 || sz[v] > sz[mxVtx]) mxVtx = v;
}
if (mxVtx != -1){
head[mxVtx] = head[u];
dfs_hld(mxVtx);
}
for (int v : son[u]){
if (v == mxVtx) continue;
head[v] = v;
dfs_hld(v);
}
tout[u] = timer;
}
node operator + (node a, node b){
node c;
c.sz = a.sz+b.sz;
c.f = a.f+b.f;
c.g = a.g+b.g;
return c;
}
void build(int id, int l, int r){
if (l == r){
int u = tour[l];
st[id].sz = 1;
st[id].f = f[u]+sumd[u];
st[id].g = g[u]+sumd[u];
return;
}
int mid = (l+r)/2;
build(2*id, l, mid);
build(2*id+1, mid+1, r);
st[id] = st[2*id]+st[2*id+1];
}
void apply(int id, tag T){
if (T.f.fi == 1) st[id].f += T.f.se*st[id].sz; else st[id].f = T.f.se*st[id].sz;
if (T.g.fi == 1) st[id].g += T.g.se*st[id].sz; else st[id].g = T.g.se*st[id].sz;
}
pii operator + (pii a, pii b){
pii c;
if (b.fi == 2) c = mp(2, b.se);
else if (a.fi == 2) c = mp(2, a.se+b.se);
else c = mp(1, a.se+b.se);
return c;
}
tag operator + (tag a, tag b){
tag c;
c.f = a.f+b.f;
c.g = a.g+b.g;
return c;
}
void down(int id){
apply(2*id, lazy[id]); apply(2*id+1, lazy[id]);
lazy[2*id] = lazy[2*id]+lazy[id]; lazy[2*id+1] = lazy[2*id+1]+lazy[id];
lazy[id] = tag();
}
void swap(int id, int l, int r, int i){
if (i < l || i > r) return;
if (l == r){
swap(st[id].f, st[id].g);
return;
}
down(id);
int mid = (l+r)/2;
swap(2*id, l, mid, i);
swap(2*id+1, mid+1, r, i);
st[id] = st[2*id]+st[2*id+1];
}
void cover(int id, int l, int r, int u, int v, pii P){
if (v < l || u > r) return;
if (l >= u && r <= v){
pii x = mp(1, 0), y = mp(1, 0);
if (P.fi != -1) x = mp(2, P.fi);
if (P.se != -1) y = mp(2, P.se);
tag T = tag(x, y);
apply(id, T);
lazy[id] = lazy[id]+T;
return;
}
down(id);
int mid = (l+r)/2;
cover(2*id, l, mid, u, v, P);
cover(2*id+1, mid+1, r, u, v, P);
st[id] = st[2*id]+st[2*id+1];
}
void add(int id, int l, int r, int u, int v, pii P){
if (v < l || u > r) return;
if (l >= u && r <= v){
tag T = tag(mp(1, P.fi), mp(1, P.se));
apply(id, T);
lazy[id] = lazy[id]+T;
return;
}
down(id);
int mid = (l+r)/2;
add(2*id, l, mid, u, v, P);
add(2*id+1, mid+1, r, u, v, P);
st[id] = st[2*id]+st[2*id+1];
}
node get(int id, int l, int r, int i){
if (l == r) return st[id];
down(id);
int mid = (l+r)/2;
if (i <= mid) return get(2*id, l, mid, i);
return get(2*id+1, mid+1, r, i);
}
void buff_f(int u, int a, int val){
while (true){
if (head[u] == head[a]){
cover(1, 1, n, tin[a], tin[u], mp(val, -1));
break;
}
cover(1, 1, n, tin[head[u]], tin[u], mp(val, -1));
u = p[head[u]];
}
}
void update(int u, int su, int a, int val){
if (u == 0 || dep[u] < dep[a]) return;
vector <int> arr = {};
while (true){
if (get(1, 1, n, tin[u]).f == get(1, 1, n, tin[su]).f){
int v = u, tmp = get(1, 1, n, tin[su]).f;
for (int i = LOG; i >= 0; i--){
if (jump[v][i] == 0 || dep[jump[v][i]] < dep[a]) continue;
if (get(1, 1, n, tin[jump[v][i]]).f == tmp) v = jump[v][i];
}
buff_f(u, v, val);
u = p[v];
}
if (u == 0 || dep[u] < dep[a]) break;
arr.push_back(u);
su = u;
u = p[u];
}
for (int u : arr){
swap(1, 1, n, tin[u]);
cover(1, 1, n, tin[u], tin[u], mp(val, -1));
}
}
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 2; i <= n; i++){
cin >> p[i];
p[i]++;
son[p[i]].push_back(i);
}
for (int i = 2; i <= n; i++){
cin >> d[i];
}
dfs_sz(1);
build_sparse();
head[1] = 1;
dfs_hld(1);
build(1, 1, n);
cout << (st[1].f+st[1].g-cur)%MOD << '\n';
cin >> q;
while (q--){
int x, y; cin >> x >> y;
x++;
cur += 2*sz[x]*y;
int u = x, tmp = get(1, 1, n, tin[x]).f+y;
for (int i = LOG; i >= 0; i--){
if (jump[u][i] == 0) continue;
if (tmp > get(1, 1, n, tin[jump[u][i]]).f) u = jump[u][i];
}
update(p[x], x, u, tmp);
u = p[u];
if (u > 0 && tmp > get(1, 1, n, tin[u]).g){
cover(1, 1, n, tin[u], tin[u], mp(-1, tmp));
}
add(1, 1, n, tin[x], tout[x], mp(y, y));
cout << (st[1].f+st[1].g-cur)%MOD << '\n';
}
return 0;
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
9 ms |
27228 KB |
Output is correct |
2 |
Correct |
8 ms |
27228 KB |
Output is correct |
3 |
Correct |
6 ms |
27228 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
556 ms |
54604 KB |
Output is correct |
2 |
Correct |
346 ms |
53192 KB |
Output is correct |
3 |
Correct |
305 ms |
53584 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
769 ms |
56492 KB |
Output is correct |
2 |
Correct |
674 ms |
58828 KB |
Output is correct |
3 |
Correct |
601 ms |
55312 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
9 ms |
27228 KB |
Output is correct |
2 |
Correct |
8 ms |
27228 KB |
Output is correct |
3 |
Correct |
6 ms |
27228 KB |
Output is correct |
4 |
Correct |
556 ms |
54604 KB |
Output is correct |
5 |
Correct |
346 ms |
53192 KB |
Output is correct |
6 |
Correct |
305 ms |
53584 KB |
Output is correct |
7 |
Correct |
769 ms |
56492 KB |
Output is correct |
8 |
Correct |
674 ms |
58828 KB |
Output is correct |
9 |
Correct |
601 ms |
55312 KB |
Output is correct |
10 |
Correct |
792 ms |
56316 KB |
Output is correct |
11 |
Correct |
692 ms |
58612 KB |
Output is correct |
12 |
Correct |
573 ms |
54708 KB |
Output is correct |
13 |
Correct |
755 ms |
58356 KB |
Output is correct |
14 |
Correct |
723 ms |
59160 KB |
Output is correct |