//============================================================================
// Name : firstTrial.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 20, MOD = 1e9 + 7;;
int seg[4 * N];
//stack<int> st[N];
vector<int> adj[N], newAdj[2 * N];
int club[N], level[N], root[N], ans[N], in[N], out[N], T, cur[N], last[N], add[N], rmove[N], addIdx, removeIdx;
pair<int,pair<int, int> > que[N];
inline void CLEAR(){
memset(newAdj, 0, sizeof newAdj);
memset(adj, 0, sizeof adj);
}
inline void dfs(int u){
newAdj[cur[club[u]]].push_back(u);
last[u] = cur[club[u]];
cur[club[u]] = u;
for(int i = 0; i < (int)adj[u].size(); i++)
dfs(adj[u][i]);
cur[club[u]] = last[u];
}
inline void simplifyTheTree(int n){
for(int i = 0; i < n; i++)
root[i] = n + i, cur[i] = n + i;// st[i].push(n + i);
dfs(0);
// for(int i = 0; i < n; i++)
// st[i].pop();
}
inline void pre(int n){
for(int i = 0; i < n; i++)
que[i].second.first = level[que[i].second.second];
sort(que, que + n);
}
inline void DFS(int u){
in[u] = T++;
for(int i = 0; i < (int)newAdj[u].size(); i++)
DFS(newAdj[u][i]);
out[u] = T - 1;
}
inline void up(int l, int r, int idx, int qidx, int val){
if(qidx < l || r < qidx)
return;
if(l == r){
seg[idx] = val;
return;
}
int mid = (l + r) / 2;
up(l, mid, idx * 2, qidx, val);
up(mid + 1, r, idx * 2 + 1, qidx, val);
seg[idx] = (0ll + seg[idx * 2] + seg[idx * 2 + 1]) % MOD;
}
inline int sum(int l, int r, int idx, int ql, int qr){
if(r < ql || qr < l)
return 0;
if(ql <= l && r <= qr)
return seg[idx];
int mid = (l + r) / 2;
return (0ll + sum(l, mid, idx * 2, ql, qr) + sum(mid + 1, r, idx * 2 + 1, ql, qr)) % MOD;
}
inline void solve(int n){
addIdx = removeIdx = -1;
bool flag;
for(int i = 0; i < n; i++){
if(i == 0 || (i && que[i].first != que[i - 1].first)){
// while(!rmove.empty()){
// int cur = rmove.top();
// up(0, 500010, 1, in[cur], 0);
// rmove.pop();
// }
while(removeIdx != -1){
int cur = rmove[removeIdx];
up(0, 500010, 1, in[cur], 0);
removeIdx--;
}
// while(!add.empty())add.pop();
addIdx = -1;
T = 0;
DFS(root[club[que[i].second.second]]);
flag = 0;
}
if(flag){
ans[que[i].second.second] = 0;
continue;
}
if((i && que[i].first == que[i - 1].first && (que[i].second.first == que[i - 1].second.first || que[i].second.first - 1 == que[i - 1].second.first))
|| (i && que[i].first != que[i - 1].first && que[i].second.first == 0) || (i == 0 && que[i].second.first == 0)){
if(i && que[i].first == que[i - 1].first && que[i].second.first != que[i - 1].second.first){
// while(!rmove.empty()){
// int cur = rmove.top();
//// cout << "rmove : " << cur << endl;
// up(0, 500010, 1, in[cur], 0);
// rmove.pop();
// }
// while(!add.empty()){
// //add have indces
// int cur = add.top();
//// cout << "Add :" << cur << ' ' << ans[cur] << endl;
// up(0, 500010, 1, in[cur], ans[cur]);
// rmove.push(cur);
// add.pop();
// }
while(removeIdx != -1){
int cur = rmove[removeIdx];
up(0, 500010, 1, in[cur], 0);
removeIdx--;
}
while(addIdx != -1){
int cur = add[addIdx];
up(0, 500010, 1, in[cur], ans[cur]);
rmove[++removeIdx] = cur;
addIdx--;
}
}
// cout << "Get answer to " << que[i][j].second << endl;
if(que[i].second.first == 0)
ans[que[i].second.second] = 1;
else
ans[que[i].second.second] = sum(0, 500010, 1, in[que[i].second.second], out[que[i].second.second]);
}else
flag = 1, ans[que[i].second.second] = 0;
// add.push(que[i][j].second);
add[++addIdx] = que[i].second.second;
}
while(removeIdx != -1){
int cur = rmove[removeIdx];
up(0, 500010, 1, in[cur], 0);
removeIdx--;
}
}
int main(){
int t;
scanf("%d", &t);
while(t--){
CLEAR();
int x, n;
scanf("%d%d", &n, &x);
for(int i = 1; i < n; i++){
int z;
scanf("%d", &z);
adj[z].push_back(i);
}
for(int i = 0; i < n; i++){
scanf("%d", &club[i]);
que[i] = make_pair(club[i], make_pair(-1, i));
}
for(int i = 0; i < n; i++)
scanf("%d", &level[i]);
pre(n);//O(n)
simplifyTheTree(n);//O(2 * n)
solve(n);
for(int i = 0; i < n; i++){
printf("%d\n", ans[i]);
}
}
return 0;
}
Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE5hbWUgOiBmaXJzdFRyaWFsLmNwcAovLyBBdXRob3IgOgovLyBWZXJzaW9uIDoKLy8gQ29weXJpZ2h0IDogWW91ciBjb3B5cmlnaHQgbm90aWNlCi8vIERlc2NyaXB0aW9uIDogSGVsbG8gV29ybGQgaW4gQysrLCBBbnNpLXN0eWxlCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwpjb25zdCBpbnQgTiA9IDVlNSArIDIwLCBNT0QgPSAxZTkgKyA3OzsKaW50IHNlZ1s0ICogTl07Ci8vc3RhY2s8aW50PiBzdFtOXTsKdmVjdG9yPGludD4gYWRqW05dLCBuZXdBZGpbMiAqIE5dOwppbnQgY2x1YltOXSwgbGV2ZWxbTl0sIHJvb3RbTl0sIGFuc1tOXSwgaW5bTl0sIG91dFtOXSwgVCwgY3VyW05dLCBsYXN0W05dLCBhZGRbTl0sIHJtb3ZlW05dLCBhZGRJZHgsIHJlbW92ZUlkeDsKcGFpcjxpbnQscGFpcjxpbnQsIGludD4gPiBxdWVbTl07CmlubGluZSB2b2lkIENMRUFSKCl7CgltZW1zZXQobmV3QWRqLCAwLCBzaXplb2YgbmV3QWRqKTsKCW1lbXNldChhZGosIDAsIHNpemVvZiBhZGopOwp9CmlubGluZSB2b2lkIGRmcyhpbnQgdSl7CgluZXdBZGpbY3VyW2NsdWJbdV1dXS5wdXNoX2JhY2sodSk7CglsYXN0W3VdID0gY3VyW2NsdWJbdV1dOwoJY3VyW2NsdWJbdV1dID0gdTsKCWZvcihpbnQgaSA9IDA7IGkgPCAoaW50KWFkalt1XS5zaXplKCk7IGkrKykKCQlkZnMoYWRqW3VdW2ldKTsKCWN1cltjbHViW3VdXSA9IGxhc3RbdV07Cgp9CmlubGluZSB2b2lkIHNpbXBsaWZ5VGhlVHJlZShpbnQgbil7Cglmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQoJCXJvb3RbaV0gPSBuICsgaSwgY3VyW2ldID0gbiArIGk7Ly8gc3RbaV0ucHVzaChuICsgaSk7CglkZnMoMCk7Ci8vCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCi8vCQlzdFtpXS5wb3AoKTsKCn0KaW5saW5lIHZvaWQgcHJlKGludCBuKXsKCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspCgkJCXF1ZVtpXS5zZWNvbmQuZmlyc3QgPSBsZXZlbFtxdWVbaV0uc2Vjb25kLnNlY29uZF07CgoJc29ydChxdWUsIHF1ZSArIG4pOwp9CgppbmxpbmUgdm9pZCBERlMoaW50IHUpewoJaW5bdV0gPSBUKys7Cglmb3IoaW50IGkgPSAwOyBpIDwgKGludCluZXdBZGpbdV0uc2l6ZSgpOyBpKyspCgkJREZTKG5ld0Fkalt1XVtpXSk7CglvdXRbdV0gPSBUIC0gMTsKfQppbmxpbmUgdm9pZCB1cChpbnQgbCwgaW50IHIsIGludCBpZHgsIGludCBxaWR4LCBpbnQgdmFsKXsKCWlmKHFpZHggPCBsIHx8IHIgPCBxaWR4KQoJCXJldHVybjsKCWlmKGwgPT0gcil7CgkJc2VnW2lkeF0gPSB2YWw7CgkJcmV0dXJuOwoJfQoJaW50IG1pZCA9IChsICsgcikgLyAyOwoJdXAobCwgbWlkLCBpZHggKiAyLCBxaWR4LCB2YWwpOwoJdXAobWlkICsgMSwgciwgaWR4ICogMiArIDEsIHFpZHgsIHZhbCk7CglzZWdbaWR4XSA9ICgwbGwgKyBzZWdbaWR4ICogMl0gKyBzZWdbaWR4ICogMiArIDFdKSAlIE1PRDsKfQppbmxpbmUgaW50IHN1bShpbnQgbCwgaW50IHIsIGludCBpZHgsIGludCBxbCwgaW50IHFyKXsKCWlmKHIgPCBxbCB8fCBxciA8IGwpCgkJcmV0dXJuIDA7CglpZihxbCA8PSBsICYmIHIgPD0gcXIpCgkJcmV0dXJuIHNlZ1tpZHhdOwoJaW50IG1pZCA9IChsICsgcikgLyAyOwoJcmV0dXJuICgwbGwgKyBzdW0obCwgbWlkLCBpZHggKiAyLCBxbCwgcXIpICsgc3VtKG1pZCArIDEsIHIsIGlkeCAqIDIgKyAxLCBxbCwgcXIpKSAlIE1PRDsKfQppbmxpbmUgdm9pZCBzb2x2ZShpbnQgbil7CglhZGRJZHggPSByZW1vdmVJZHggPSAtMTsKCWJvb2wgZmxhZzsKCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspewoJCWlmKGkgPT0gMCB8fCAoaSAmJiBxdWVbaV0uZmlyc3QgIT0gcXVlW2kgLSAxXS5maXJzdCkpewoJLy8JCXdoaWxlKCFybW92ZS5lbXB0eSgpKXsKCS8vCQkJaW50IGN1ciA9IHJtb3ZlLnRvcCgpOwoJLy8JCQl1cCgwLCA1MDAwMTAsIDEsIGluW2N1cl0sIDApOwoJLy8JCQlybW92ZS5wb3AoKTsKCS8vCQl9CgkJCXdoaWxlKHJlbW92ZUlkeCAhPSAtMSl7CgkJCQlpbnQgY3VyID0gcm1vdmVbcmVtb3ZlSWR4XTsKCQkJCXVwKDAsIDUwMDAxMCwgMSwgaW5bY3VyXSwgMCk7CgkJCQlyZW1vdmVJZHgtLTsKCQkJfQoJLy8JCXdoaWxlKCFhZGQuZW1wdHkoKSlhZGQucG9wKCk7CgkJCWFkZElkeCA9IC0xOwoJCQlUID0gMDsKCQkJREZTKHJvb3RbY2x1YltxdWVbaV0uc2Vjb25kLnNlY29uZF1dKTsKCQkJZmxhZyA9IDA7CgkJfQoJCWlmKGZsYWcpewoJCQlhbnNbcXVlW2ldLnNlY29uZC5zZWNvbmRdID0gMDsKCQkJY29udGludWU7CgkJfQoJCWlmKChpICYmIHF1ZVtpXS5maXJzdCA9PSBxdWVbaSAtIDFdLmZpcnN0ICYmIChxdWVbaV0uc2Vjb25kLmZpcnN0ID09IHF1ZVtpIC0gMV0uc2Vjb25kLmZpcnN0IHx8IHF1ZVtpXS5zZWNvbmQuZmlyc3QgLSAxID09IHF1ZVtpIC0gMV0uc2Vjb25kLmZpcnN0KSkKCQkJCXx8IChpICYmIHF1ZVtpXS5maXJzdCAhPSBxdWVbaSAtIDFdLmZpcnN0ICYmIHF1ZVtpXS5zZWNvbmQuZmlyc3QgPT0gMCkgfHwgKGkgPT0gMCAmJiBxdWVbaV0uc2Vjb25kLmZpcnN0ID09IDApKXsKCQkJaWYoaSAmJiBxdWVbaV0uZmlyc3QgPT0gcXVlW2kgLSAxXS5maXJzdCAmJiBxdWVbaV0uc2Vjb25kLmZpcnN0ICE9IHF1ZVtpIC0gMV0uc2Vjb25kLmZpcnN0KXsKLy8JCQkJCQl3aGlsZSghcm1vdmUuZW1wdHkoKSl7Ci8vCQkJCQkJCWludCBjdXIgPSBybW92ZS50b3AoKTsKLy8vLwkJCQkJCQljb3V0IDw8ICJybW92ZSA6ICIgPDwgY3VyIDw8IGVuZGw7Ci8vCQkJCQkJCXVwKDAsIDUwMDAxMCwgMSwgaW5bY3VyXSwgMCk7Ci8vCQkJCQkJCXJtb3ZlLnBvcCgpOwovLwkJCQkJCX0KLy8JCQkJCQl3aGlsZSghYWRkLmVtcHR5KCkpewovLwkJCQkJCQkvL2FkZCBoYXZlIGluZGNlcwovLwkJCQkJCQlpbnQgY3VyID0gYWRkLnRvcCgpOwovLy8vCQkJCQkJCWNvdXQgPDwgIkFkZCA6IiA8PCBjdXIgPDwgJyAnIDw8IGFuc1tjdXJdIDw8IGVuZGw7Ci8vCQkJCQkJCXVwKDAsIDUwMDAxMCwgMSwgaW5bY3VyXSwgYW5zW2N1cl0pOwovLwkJCQkJCQlybW92ZS5wdXNoKGN1cik7Ci8vCQkJCQkJCWFkZC5wb3AoKTsKLy8JCQkJCQl9CgkJCQl3aGlsZShyZW1vdmVJZHggIT0gLTEpewoJCQkJCWludCBjdXIgPSBybW92ZVtyZW1vdmVJZHhdOwoJCQkJCXVwKDAsIDUwMDAxMCwgMSwgaW5bY3VyXSwgMCk7CgkJCQkJcmVtb3ZlSWR4LS07CgkJCQl9CgkJCQl3aGlsZShhZGRJZHggIT0gLTEpewoJCQkJCWludCBjdXIgPSBhZGRbYWRkSWR4XTsKCQkJCQl1cCgwLCA1MDAwMTAsIDEsIGluW2N1cl0sIGFuc1tjdXJdKTsKCQkJCQlybW92ZVsrK3JlbW92ZUlkeF0gPSBjdXI7CgkJCQkJYWRkSWR4LS07CgkJCQl9CgkJCX0KLy8JCQkJY291dCA8PCAiR2V0IGFuc3dlciB0byAiIDw8IHF1ZVtpXVtqXS5zZWNvbmQgPDwgZW5kbDsKCQkJaWYocXVlW2ldLnNlY29uZC5maXJzdCA9PSAwKQoJCQkJYW5zW3F1ZVtpXS5zZWNvbmQuc2Vjb25kXSA9IDE7CgkJCWVsc2UKCQkJCWFuc1txdWVbaV0uc2Vjb25kLnNlY29uZF0gPSBzdW0oMCwgNTAwMDEwLCAxLCBpbltxdWVbaV0uc2Vjb25kLnNlY29uZF0sIG91dFtxdWVbaV0uc2Vjb25kLnNlY29uZF0pOwoKCQl9ZWxzZQoJCQlmbGFnID0gMSwgYW5zW3F1ZVtpXS5zZWNvbmQuc2Vjb25kXSA9IDA7Ci8vCQkJYWRkLnB1c2gocXVlW2ldW2pdLnNlY29uZCk7CgkJYWRkWysrYWRkSWR4XSA9IHF1ZVtpXS5zZWNvbmQuc2Vjb25kOwoKCX0KCXdoaWxlKHJlbW92ZUlkeCAhPSAtMSl7CgkJaW50IGN1ciA9IHJtb3ZlW3JlbW92ZUlkeF07CgkJdXAoMCwgNTAwMDEwLCAxLCBpbltjdXJdLCAwKTsKCQlyZW1vdmVJZHgtLTsKCX0KfQoKCmludCBtYWluKCl7CglpbnQgdDsKCXNjYW5mKCIlZCIsICZ0KTsKCXdoaWxlKHQtLSl7CgkJQ0xFQVIoKTsKCQlpbnQgeCwgbjsKCQlzY2FuZigiJWQlZCIsICZuLCAmeCk7CgkJZm9yKGludCBpID0gMTsgaSA8IG47IGkrKyl7CgkJCWludCB6OwoJCQlzY2FuZigiJWQiLCAmeik7CgkJCWFkalt6XS5wdXNoX2JhY2soaSk7CgkJfQoJCWZvcihpbnQgaSA9IDA7IGkgPCBuOyBpKyspewoJCQlzY2FuZigiJWQiLCAmY2x1YltpXSk7CgkJCXF1ZVtpXSA9IG1ha2VfcGFpcihjbHViW2ldLCBtYWtlX3BhaXIoLTEsIGkpKTsKCQl9CgkJZm9yKGludCBpID0gMDsgaSA8IG47IGkrKykKCQkJc2NhbmYoIiVkIiwgJmxldmVsW2ldKTsKCQlwcmUobik7Ly9PKG4pCgkJc2ltcGxpZnlUaGVUcmVlKG4pOy8vTygyICogbikKCgkJc29sdmUobik7CgkJZm9yKGludCBpID0gMDsgaSA8IG47IGkrKyl7CgkJCXByaW50ZigiJWRcbiIsIGFuc1tpXSk7CgkJfQoJfQoJcmV0dXJuIDA7Cn0K