之前才学会dsu on tree这种奇怪的算法,没想到现在就能用上(
代码有点复杂,但好处是根本不用动脑,套3步公式(遍历轻儿子,遍历重儿子,计算轻儿子)就可以直接AC
建议标签加上dsu on tree
(话说好像大部分能用dsu on tree的题都没有加这个标签
#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define lowbit(x) x & -x
using namespace std;
const int N = 1e5+10;
int n,m;
vector<int> vec[N];
int hson[N],sz[N];
int c[N];
int ans[N];
int HH;
struct node{
int id,num;
}a[N],b[N];
inline bool cmp(node x,node y){
return x.num<y.num;
}
inline void add(int x,int val){
while(x<=n){
c[x] += val;
x += lowbit(x);
}
}
inline int query(int x){
int res = 0;
while(x){
res += c[x];
x -= lowbit(x);
}
return res;
}
inline void dfs(int x,int fa){
sz[x] = 1;
for(int i=0;i<vec[x].size();i++){
int v = vec[x][i];
if(v==fa) continue;
dfs(v,x);
sz[x] += sz[v];
if(sz[v] > sz[hson[x]]){
hson[x] = v;
}
}
}
inline void calc(int x,int fa,int val){
add(a[x].num,val);
for(int i=0;i<vec[x].size();i++){
int v = vec[x][i];
if(v==fa || v==HH) continue;
calc(v,x,val);
}
}
inline void dsu(int x,int fa,int op){
for(int i=0;i<vec[x].size();i++){
int v = vec[x][i];
if(v==fa || v==hson[x]) continue;
dsu(v,x,0);
}
if(hson[x]){
dsu(hson[x],x,1);
HH = hson[x];
}
calc(x,fa,1);
ans[x] = sz[x]-query(a[x].num);
HH = 0;
if(!op){
calc(x,fa,-1);
}
}
signed main(){
ios::sync_with_stdio(false);
cin>>n;
int q1;
for(int i=1;i<=n;i++){
cin>>a[i].num;
a[i].id = i;
b[i] = {i,a[i].num};
}
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++){
a[b[i].id].num = i;
}
for(int i=2;i<=n;i++){
cin>>q1;
vec[q1].push_back(i);
vec[i].push_back(q1);
}
dfs(1,0);
dsu(1,0,0);
for(int i=1;i<=n;i++){
cout<<ans[i]<<endl;
}
return 0;
}