Segment tree merger bare title, in fact, this question can be seen as the number of points for each of the sub-tree point larger than its right value. This question is to see the range of values, know to use dynamic segment tree open point, then we can p array of discrete, each point corresponding to build a range tree line. Finally, starting from the root traversal, backtracking point when there will be boss and subordinate relationships can be merged.
The key is to merge operations:
But it is still well understood, my code does not open a new node, equivalent to merge onto y x, starting from the root down to recursively update, it is quite violent.
The complete code is as follows:
#include<bits/stdc++.h> using namespace std; const int maxn=3e6+7; struct node{ int nxt; int to; }edge[maxn*2]; int lc[maxn],rc[maxn]; int T; int a[maxn],p[maxn]; int root[maxn]; struct seg{ int val; }tree[maxn*3]; int head[maxn],tot; int n; int x; int neww; int ans[maxn]; void add(int x,int y){ edge[++tot].nxt=head[x]; edge[tot].to=y; head[x]=tot; } void build(int &node,int l,int r,int x){ if(!node) node=++T; if(l==r){ tree[node].val++; return; } int mid=(l+r)>>1; if(x<=mid){ build(lc[node],l,mid,x); } else{ build(rc[node],mid+1,r,x); } tree[node].val=tree[lc[node]].val+tree[rc[node]].val; } void merge(int &x,int y){ if(!x||!y){ x=x+y; return; } tree[x].val=tree[x].val+tree[y].val; merge(lc[x],lc[y]); merge(rc[x],rc[y]); } int query(int node,int l,int r,int v){ if(l==r) return 0; int mid=(l+r)>>1; if(v<=mid) return query(lc[node],l,mid,v)+tree[rc[node]].val; else return query(rc[node],mid+1,r,v); } void dfs(int x){ for(int i=head[x];i;i=edge[i].nxt){ int v=edge[i].to; dfs(v); merge(root[x],root[v]);//回溯时暴力合并 } ans[x]=query(root[x],1,neww,p[x]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&p[i]); a[i]=p[i]; } std::sort(a+1,a+1+n); neww=unique(a+1,a+1+n)-a-1; for(int i=2;i<=n;i++){ scanf("%d",&x); add(x,i); } for(int i=1;i<=n;i++){ p[i]=lower_bound(a+1,a+1+neww,p[i])-a;//离散化 build(root[i],1,neww,p[i]); } dfs(1); for(int i=1;i<=n;i++){ printf("%d\n",ans[i]); } return 0; }