Overstaffed Company


Time Limit: 10 Seconds       Memory Limit: 32768 KB


Incredible Crazily Progressing Company (ICPC) is facing the problem of overstaffing. It contains several departments and each department may also have underlying departments. Each department may have some managers. Today, the leading manager of the company wants to reduce the stafftrimmer. However, he doesn't know which department has most redundant managers. He needs you to find the number of underlying departments that have more managers than that department for each department.

Input

The first line of each test case contains a positive integer n not exceeding 50000, indicating the number of departments that number from 0 to n - 1. The next line contains n - 1 integers, the i-th of which indicates the i-th department's superior department and is less than i. Note that all the departments except the zeroth has a superior department and they are all the zeroth one's underlying departments. The third line contains n integers not exceeding 1000000, indicating the number of managers of each department.

Output

Output n integers in a line indicating the number of underlying departments that have more managers than that department in the order according to the department number.

Sample Input


6
0 0 1 2 2
10 7 4 8 5 12



Sample Output



1 1 2 0 0 0



Hint: Department 5 has more managers than Department 0. Department 3 has more managers than Department 1. Department 4 and 5 have more managers than Department 2.




dfs序中用树状数组就可以搞定了,结果偶弱智,想了太多的用了主席树。。。



#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 50005;
int n, m, x, cnt[maxn], ans[maxn], tot;
vector<int> p[maxn];

struct ST
{
#define maxn 1200005
int L[maxn], R[maxn], n, m, t, f[maxn], frist[maxn];
void build(int x, int y)
{
t = n = x; m = y;
for (int i = 0; i <= n; i++)
{
L[i] = R[i] = f[i] = 0;
frist[i] = i;
}
}
int newnode()
{
++t;
L[t] = R[t] = f[t] = 0;
return t;
}
void insert(int x, int y)
{
int bef = frist[x - 1], now = frist[x];
int l = 0, r = m, mid;
for (; l <= r;)
{
f[now] = f[bef] + 1;
L[now] = L[bef]; R[now] = R[bef];
if (l == r) break;
mid = (l + r) >> 1;
if (y <= mid)
{
r = mid; L[now] = newnode();
now = L[now]; bef = L[bef];
}
else
{
l = mid + 1; R[now] = newnode();
now = R[now]; bef = R[bef];
}
}
}
int find(int bef, int now, int l, int r, int limit)
{
if (r <= limit) return f[now] - f[bef];
int mid = (l + r) >> 1, ans = 0;
ans += find(L[bef], L[now], l, mid, limit);
if (limit > mid) ans += find(R[bef], R[now], mid + 1, r, limit);
return ans;
}
int query(int l, int r, int limit)
{
int bef = frist[l - 1], now = frist[r];
return find(bef, now, 0, m, limit);
}
}st;

void dfs(int x)
{
st.insert(++tot, cnt[x]);
ans[x] = tot - st.query(1, tot, cnt[x]);
for (int i = 0; i < p[x].size(); i++) dfs(p[x][i]);
ans[x] = tot - st.query(1, tot, cnt[x]) - ans[x];
}

int main()
{
while (scanf("%d", &n) != EOF)
{
for (int i = 0; i < n; i++) p[i].clear();
for (int i = 1; i < n; i++)
{
scanf("%d", &x);
p[x].push_back(i);
}
for (int i = tot = x = 0; i < n; i++) scanf("%d", &cnt[i]), x = max(x, cnt[i]);
st.build(n, x);
dfs(0);
for (int i = 0; i < n; i++) printf("%s%d", i ? " " : "", ans[i]);
putchar(10);
}
return 0;
}