We can solve all the problems with the tree array, I use the bucket and this to indicate the number of the largest can be directly to the prefix and
#include <cstdio>#include<algorithm>#defineMAXN 100010using namespaceStd;inlineintRead () {intsum=0; CharCh=GetChar (); while(ch<'0'|| Ch>'9') ch=GetChar (); while(ch>='0'&&ch<='9') {sum= (sum<<1) + (sum<<3) +ch-'0'; CH=GetChar (); } returnsum;}intP[MAXN],H[MAXN];intn,m;structvia{intTo,next;} C[MAXN];intHead[maxn],t;inlinevoidAddintXinty) {c[++t].to=y; C[t].next=Head[x]; HEAD[X]=T;} InlineintSum_h (intx) { intsum=0; while(x>0) sum+=h[x],x-=x& (-x); returnsum;} InlineintSum_p (intx) { intsum=0; while(x>0) sum+=p[x],x-=x& (-x); returnsum;} InlinevoidIns_p (intXintkey) { while(x<=n) p[x]+=key,x+=x& (-x);} InlinevoidIns_h (intXintkey) { while(x<=n) h[x]+=key,x+=x& (-x);}intA[MAXN],POS[MAXN];intans[maxn][3];intCompConst intXConst inty) { returnA[x]>a[y];} InlinevoidInit () {scanf ("%d",&N); for(intI=2, x;i<=n;i++) x=read (), add (x,i); for(intI=1; i<=n;i++) A[i]=read (), pos[i]=i; Sort (POS+1, pos+n+1, comp); for(intI=1; i<=n;i++) a[pos[i]]=i;}voidDfsintx) {Ins_h (a[x],1); intY=sum_h (a[x]-1); ans[x][2]=sum_p (a[x]-1); Ins_p (A[x],1); for(intI=head[x];i;i=c[i].next) DFS (c[i].to); ans[x][1]=sum_h (a[x]-1)-y; Ins_p (A[x],-1); ans[x][0]=a[x]-1-ans[x][1];} InlinevoidWork () {DFS (1); for(intI=1; i<=n;i++) printf ("%d%d%d\n", ans[i][1],ans[i][0],ans[i][2]);}intMain () {Init (); Work (); return 0;}
[COGS 1535] [ZJOI2004] Tree Fruit tree array + bucket