// 可以理解为从 某个点 u 出发,然后每次只能往上走
// 寻找最长的序列的长度,使得经过的 w[i] 的和 小于等于 c[u]
// 走的时候可以倍增走,快速走, 最后的结果就是 深度的差值
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
#define int long long
vector<int> e[N];
int n, sum[N], w[N], c[N];
int f[N][25];
int dep[N];
void dfs(int u, int fa) {
sum[u] = sum[fa] + w[u]; //类似前缀和
dep[u] = dep[fa] + 1;
f[u][0] = fa;
for (int i = 1; i < 20; i++)
f[u][i] = f[f[u][i - 1]][i - 1];
for (auto v : e[u]) {
dfs(v, u);
}
}
signed main() {
cin >> n;
for (int i = 2; i <= n; i++) {
int x;
cin >> x;
e[x].push_back(i); // 记录他的子节点
}
for (int i = 1; i <= n; i++)
cin >> w[i];
for (int i = 1; i <= n; i++)
cin >> c[i];
dfs(1, 0);
for (int i = 1; i <= n; i++) {
int u = i;
for (int j = 19; j >= 0; j--) {
if (f[u][j] == 0) continue;
// 求区间和
// 计算的区间和是 从 i 到 f[u][j] 之间的和
if (sum[i] - sum[f[u][j]] + w[f[u][j]] <= c[i])
u = f[u][j];
}
cout << dep[i] - dep[u] + 1 << " ";
}
return 0;
}
// 有很多的等差数列
// 每个位置上有一个人,最多只会有一个位置是奇数
// 求这个位置,这个位置的人数
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
#define int long long
int n, s[N], e[N], d[N];
int T;
int ans, cnt;
int get(int x) {
int sum = 0;
for (int i = 1 ; i <= n; i++) {
if (x < s[i])
continue;
sum += (min(x, e[i]) - s[i]) / d[i] + 1;
}
return sum;
}
signed main() {
cin >> T;
while (T--) {
cin >> n;
int sum = 0;
int maxx = 0;
for (int i = 1 ; i <= n; i++) {
cin >> s[i] >> e[i] >> d[i];
sum += (e[i] - s[i]) / d[i] + 1;
maxx = max(maxx, e[i]);
}
if (sum % 2 == 0) {
cout << "Poor QIN Teng:( \n";
continue;
} else {
int l = 0;
int t = 1; // 第一次的区间长度
while (t) { // 最后结束变成一个点
// get(x) 求的是 [1,x] 的和
if ( l + t <= maxx && get(l + t) % 2 == 0 ) {
l += t;
t = t * 2;
} else
t = t / 2;
}
// 找到了奇数的位置
ans = l + 1, cnt = 0;
// 计算这个位置有多少个人
for (int i = 1; i <= n; i++) {
if (s[i] <= ans && ans <= e[i] && (ans - s[i]) % d[i] == 0)
cnt++;
}
cout << ans << " " << cnt << endl;
}
}
return 0;
}




// last[value]表示盈利值 value 最近出现的位置
// st[i]表示第i个数为结尾的最长完美序列的起始位置
// st[i] = max(st[i-1] , last[a[i]]+1)
// f[i] 表示以第 i 个数结尾的最长完美序列的长度
// f[i] = i - st[i]+1
// st值为非递减序列,对于询问区间 [li,ri]
// 该区间的 st 值可能会出现:左边一部分的 st 值不在区间内,即小于 li
// 右边一部分的 st 值大于等于 li
// st 值具有单调性,可以通过二分得到, 假设这个位置为 mid
// 则 st[li...mi-1] < li, st[mi...ri]>li
// 所以最后的结果为:左边部分的结果为 mid - li
// 右边部分的结果为:[mid, ri] 的最大值,用 ST 算法来求
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1e6+10;
int last[M << 1], mx[N][20];
int f[N], st[N], lg[N];
int n, m, l, r, x;
int find(int l1, int r1) {
// 当 mi 等于 l1 时,左边部分的最大值为0,不用考虑
if (st[l1] == l1) return l1;
// 当 mi 小于 l1 时,不存在左边部分,不用考虑
if (st[r1] < l1) return r1 + 1;
int l = l1, r = r1;
while (l <= r) {
int mid = l + r >> 1;
if (st[mid] < l1) l = mid + 1;
else r = mid - 1;
}
return l;
}
int query(int l, int r) {
int x = lg[r - l + 1];
return max(mx[l][x], mx[r - (1 << x) +1][x]);
}
int main() {
scanf("%d%d", &n, &m);
lg[0] = -1;
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
// x+M 拒绝负数下标
st[i] = max(st[i - 1], last[x + M] + 1);
f[i] = i - st[i] + 1;
lg[i] = lg[i / 2] + 1;
last[x + M] = i;
}
for (int i = 1; i <= n; i++)
mx[i][0] = f[i];
for (int j = 1; j <= lg[n]; j++) {
for (int i = 1; i + (1 << j - 1) <= n; i++) {
mx[i][j] = max(mx[i][j - 1], mx[i + (1 << j - 1)][j - 1]);
}
}
while (m--) {
scanf("%d%d", &l, &r);
++l, ++r;
int mid = find(l, r), ans = 0, tmp;
if (mid > l) ans = mid - l;
if (mid <= r) {
tmp = query(mid, r);
ans = max(ans, tmp);
}
printf("%d\n", ans);
}
return 0;
}
//st[i][j] 从i位置开始,往后2^j个位置的最大值,包含i位置
//st[i][j] = max(a[i] , a[i+1] ... a[i+2^j-1])
//st[i][0] = a[i]
//2^j = 2^(j-1) + 2^(j-1)
//
//
//st[i][j] = max(st[i][j-1] , st[i+(1<<j-1)][j-1])
//
//st[i][j] = max(a[i] , a[i+1] ... a[i+2^j-1])
//
//st[i][j-1] = max(a[i] , a[i+1] ... a[i+2^(j-1)-1])
//st[i+(1<<j-1)][j-1] = max(a[i+ 2^(j-1)] ....a[i+2^j-1])
//
//for(int i=1;i<=n;i++)
// st[i][0] =a[i]
//for(int j= 1;(1<<j)<=n;j++){
// for(int i=1;i+(1<<j)-1<=n;i++)
// st[i][j] = max(st[i][j-1] , st[i+(1<<j-1)][j-1]);
//}
//
//st[i][j] 从 i 开始往后 2^j 个数字的最大值
//求 [l,r] 区间的最大值 ???
//
//len = r - l+1
//第一个区间是从 l 开始往后走 len , 最好的结果是等于 len, 小于等于的最大
//第二个区间是 r - len 开始走 len
//2^j = len, j 等于 log_2(len)
//
//l,r的最大值 max( st[l][log(len)] , st[r -(1<<log2(len))+1][log(len)])
//
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N], st[N][20];
int lg[N];
void init() {
lg[1] = 0; // 2^0 =1
for (int i = 2; i <= n; i++)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i <= n; i++)
st[i][0] = a[i];
for (int j = 1; j <= lg[n]; j++) {
for (int i = 1; i + (1 << j - 1) <= n; i++)
st[i][j] = max(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
}
}
int query(int l, int r) {
int len = r - l + 1;
int res = max(st[l][lg[len]], st[r - (1 << lg[len]) + 1][lg[len]]);
return res;
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
init();
while (m--) {
int l, r;
cin >> l >> r;
cout << query(l, r) << '\n';
}
return 0;
}