用的是二分答案的方法。
感觉挺好写并且挺直观的但是死活没调出来。
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
#define ll long long
int inline read() {
int num = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-')f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
num = (num << 3) + (num << 1) + (ch ^ 48);
ch = getchar();
}
return num * f;
}
int n, tim, dfn[N];
ll ma, a[N], b[N], lazy[N];
vector<int>e[N];
void add(int u, int v) {
e[u].emplace_back(v);
}
void init(int u) {
dfn[++tim] = u;
for(int v : e[u])init(v);
}
bool check(ll k) {
for(int i = 1; i <= n; i++)b[i] = a[i];
for(int i = 1; i <= n; i++)lazy[i] = 0;
b[1] -= k;
for(int i = 1; i <= n; i++) {
int u = dfn[i];
bool f = 0;
lazy[u] += max(0ll, -b[u]);
for(int v : e[u]) {
f = 1;
b[v] -= lazy[u];
lazy[v] += lazy[u];
}
if(!f && b[u] < 0)return false;
}
return true;
}
void solve() {
n = read(), ma = 0;
for(int i = 1; i <= n; i++)e[i].clear();
for(int i = 1; i <= n; i++)a[i] = read(), ma = max(ma, 2 * a[i]);
for(int i = 2; i <= n; i++) add(read(), i);
tim = 0, init(1);
ll l = a[1], r = ma;
while(l < r) {
ll mid = l + r + 1 >> 1;
if(check(mid))l = mid;
else r = mid - 1;
}
printf("%lld\n", l);
}
int main() {
#ifdef file
freopen("D.in", "r", stdin);
freopen("D.out", "w", stdout);
#endif
int T = read();
while(T--)solve();
return 0;
}