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]); }