C87 树状数组+DFS P3605 [USACO17JAN] Promotion Counting P

视频链接:C87 树状数组+DFS P3605 [USACO17JAN] Promotion Counting P_哔哩哔哩_bilibili

 

 

Luogu P3605 [USACO17JAN] Promotion Counting P

// 树状数组+DFS O(nlogn)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

#define lowb(x) x&-x
const int N=100005;
int h[N],to[N],ne[N],idx;
void add(int a,int b){ //连边
  to[++idx]=b;ne[idx]=h[a];h[a]=idx;
}
int n,p[N],b[N],s[N],ans[N];
void change(int x,int k){ //向后修
  while(x<=n) s[x]+=k,x+=lowb(x);
}
int query(int x){ //向前查
  int t=0;
  while(x) t+=s[x],x-=lowb(x);
  return t;
}
void dfs(int x){
  ans[x]-=(query(n)-query(p[x])); //前面比px大的
  for(int i=h[x];i;i=ne[i]) dfs(to[i]);
  ans[x]+=(query(n)-query(p[x])); //现在比px大的
  change(p[x],1); //[px,n]均+1
}
int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;i++)scanf("%d",p+i),b[i]=p[i];
  sort(b+1,b+n+1);
  for(int i=1;i<=n;i++)
    p[i]=lower_bound(b+1,b+n+1,p[i])-b; //离散化
  for(int i=2,x;i<=n;i++)scanf("%d",&x),add(x,i);
  dfs(1);
  for(int i=1;i<=n;i++) printf("%d\n",ans[i]);
}

 

posted @ 2024-01-04 18:10  董晓  阅读(141)  评论(0编辑  收藏  举报