Counting Offspring
HDU-3887
Ask you how many of the points on each node it has on its sub-tree that are smaller than it
/*subtree problem, DFS sequence can be easily solved, because point in its sub-tree, so in the line segment tree, it must be between its two timestamp interval, so we just need to consider from small to large, its interval of how many points have been put, and then put it in. It is easy to solve the last number of each line after the output of the extra space, otherwise the PE*/#include<iostream>#include<cstdio>#include<cstring>#defineMAXN 100010using namespacestd;intN,p,num,head[maxn],xu[maxn],sz[maxn],opx,opl,opr;structnode{intTo,pre;} e[maxn*2];structnode{intL,r,v;} tr[maxn<<4];voidInsert (int from,intTo ) {e[++num].to=to ; E[num].pre=head[ from]; head[ from]=num;}voidBuildintLintRintk) {TR[K].L=l;tr[k].r=r;tr[k].v=0; if(L==R)return; intMid= (l+r) >>1; Build (L,mid,k<<1); Build (Mid+1,r,k<<1|1);}intID;voidDfsintNowintfather) {Xu[now]=++ID; Sz[now]=1; for(intI=head[now];i;i=e[i].pre) { intto=e[i].to; if(To==father)Continue; DFS (To,now); Sz[now]+=Sz[to]; }}intQueryintLintRintk) { if(L>=OPL&&R<=OPR) {returnTR[K].V;} intMid= (l+r) >>1; intres=0; if(Opl<=mid) Res+=query (l,mid,k<<1); if(Opr>mid) Res+=query (mid+1,r,k<<1|1); returnRes;}voidChangeintLintRintk) { if(L==R) {tr[k].v++;return;} intMid= (l+r) >>1; if(opx<=mid) Change (l,mid,k<<1); ElseChange (mid+1,r,k<<1|1); TR[K].V=tr[k<<1].v+tr[k<<1|1].v;}intMain () {Freopen ("Cola.txt","R", stdin); while(1) {scanf ("%d%d",&n,&p); if(n==0&&p==0)return 0; memset (Head,0,sizeof(head)); Memset (E,0,sizeof(e)); num=0; ID=0; Build (1N1); intx, y; for(intI=1; i<n;i++) {scanf ("%d%d",&x,&y); Insert (x, y); insert (y,x); } DFS (P,0); for(intI=1; i<=n;i++) {OPL=xu[i],opr=xu[i]+sz[i]-1; if(i!=n) printf ("%d", Query (1N1)); Elseprintf"%d", Query (1N1)); OPX=Xu[i]; Change (1N1); } puts (""); }}
hdu3887 counting Offspring