#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;

#define ll long long
#define pi pair<int,int>
#define x first
#define y second
#define mp make_pair
#define NMAX 100005
#define pb push_back

vector<int> v[NMAX];
ll value[NMAX],bigvalue[NMAX],sol[NMAX];
ll subarbore[NMAX],sp[NMAX];
ll euler[NMAX],finaleuler[NMAX];
ll valuevalue[NMAX][2];
int n;
ll eulerval,nr;
pi event[2 * NMAX];
char viz[NMAX];
ll aint[5 * NMAX];

inline int cmp(const pi& a, const pi& b)
{
    if(valuevalue[a.x][a.y] == valuevalue[b.x][b.y])
    {
        if(a.y == b.y)
            return a.x < b.x;
        return a.y < b.y;
    }
    return valuevalue[a.x][a.y] < valuevalue[b.x][b.y];
}

inline void dfs(int nod)
{
    euler[nod] = ++eulerval;
    viz[nod] = 1;
    int i,vec,lim = v[nod].size();
    for(i = 0; i < lim; i++)
        if(!viz[vec = v[nod][i]])
            dfs(vec);
    finaleuler[nod] = eulerval;
}

void update(int n, int st, int dr, int poz, int val)
{
    if(st == dr)
    {
        aint[n] = val;
        return ;
    }
    int mij = (st + dr) / 2;
    if(poz <= mij)
        update(2 * n, st, mij, poz, val);
    else
        update(2 * n + 1, mij + 1, dr, poz, val);
    aint[n] = aint[2 * n] + aint[2 * n + 1];
}

ll query(int n, int st, int dr, int a, int b)
{
  //  printf("Query pe %d %d %d %d\n",st,dr,a,b);
    if(a <= st && dr <= b)
    {
    //    printf("Returneaza %lld\n",aint[n]);
        return aint[n];
    }
    int mij = (st + dr) / 2;
    ll v1 = 0, v2 = 0;
   // printf("mijlocul e %d\n",mij);
    if(a <= mij)
        v1 = query(2 * n, st, mij, a, b);
    if(b > mij)
        v2 = query(2 * n + 1, mij + 1, dr, a, b);
    //printf("Returneaza %lld\n",v1,v2);
    return v1 + v2;
}

int main ()
{
    int i,t,j,nod,lim,vec;

  //  freopen("a.in","r",stdin);
   // freopen("a.out","w",stdout);

    scanf("%d",&n);
    for(i = 2; i <= n; i++)
    {
        scanf("%d",&t);
        v[t].pb(i);
    }
    for(i = 1; i <= n; i++)
    {
        scanf("%lld",&value[i]);
        event[++nr] = mp(i,0);
        valuevalue[i][0] = value[i];
    }
    for(i = 1; i <= n; i++)
    {
        scanf("%lld",&bigvalue[i]);
        event[++nr] = mp(i,1);
        valuevalue[i][1] = bigvalue[i];
    }
    sort(event + 1, event + nr + 1, cmp);

    dfs(1);

    for(i = 1; i <= nr; i++)
    {
     //   printf("%d %d\n",event[i].x,event[i].y);
        if(event[i].y == 0)
        {
            update(1,1,n,euler[event[i].x],1);
       //     printf("La %lld am pus 1(nodul %d)\n", euler[event[i].x],event[i].x);
        }
        else
        {
            nod = event[i].x;
            lim = v[nod].size();
        //    printf("Pentru nodul %d am %lld %lld\n",nod,euler[nod],finaleuler[nod]);
            for(j = 0; j < lim; j++)
            {
                vec = v[nod][j];
                subarbore[j + 1] = query(1,1,n,euler[vec],finaleuler[vec]);
          //      printf("Subarbore de vecinul %d este %lld cu inter %lld %lld\n",vec,subarbore[j + 1],euler[vec],finaleuler[vec]);
            }
            for(j = 1; j <= lim; j++)
            {
                sol[nod] += sp[j - 1] * subarbore[j];
                sp[j] = sp[j - 1] + subarbore[j];
            }
            sol[nod] *= 2;
            if(value[nod] <= bigvalue[nod])
                sol[nod] += 2 * sp[lim] + 1;

        }
    }
    for(i = 1; i <= n; i++)
        printf("%lld\n",sol[i]);

    return 0;
}