#include #include #include using namespace std; #define ll long long #define pi pair #define x first #define y second #define mp make_pair #define NMAX 100005 #define pb push_back vector 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; }