Topic links
Main topic:
There was an n-node tree and N-head cows, and at first all cows were at one junction, and the cows would go to their destination in order from number 1 to number n, asking each cow how many already had a cow's knot on its way to its destination.
Exercises
It can be found that every cow arriving at its destination will only contribute to the answer of a cow that has not yet reached its destination in the subtree of its destination.
For example, in the following tree, a cow arrives at the dark knot in the map, and in a cow that has not yet reached its destination, only the cows that are destined for the dark knot tree will contribute to the answer by dark nodes.
So, after each cow arrives at the destination, we can add a weight to each node in the subtree of the node where the destination is located, and when asked, output the weight of the node at the point where the cow is destined.
Since each modification is performed in a subtrees tree, consider using DFS sequence to give the node number (because the DFS order of the nodes in each subtrees tree must be a continuous segment), and then use the line tree for maintenance.
Code:
#include <iostream>#include<cstdio>using namespacestd;structedge{intLast ; intend;} e[200005]; intNe=0, idx=0, dfn[100005],note[100005],size[100005],tree[400005],lazy[400005];voidMake_edge (intUintv) {NE++; E[ne].last=Note[u]; E[ne].end=v; Note[u]=NE;}voidDfsintXintFX) {Dfn[x]=++idx;//number nodes with DFS sequencesize[x]=1; for(intI=note[x];i;i=e[i].last)if(e[i].end!=FX) {DFS (e[i].end,x);//Continue DFS//calculates the subtree size of each node, which is used to calculate the maximum number of Dfs orders in the subtree of this node and is easy to operatesize[x]+=Size[e[i].end]; }}//Line Tree BoardvoidAdd_node (intPintLintRintk) {Tree[p]+ = (r-l+1)*K; LAZY[P]+=K;}voidClean_lazy (intPintLintR) { intMid= (l+r) >>1; Add_node (P<<1), l,mid,lazy[p]); Add_node (P<<1)+1, mid+1, R,lazy[p]); LAZY[P]=0;}voidAddintPintLintRintXinty) { if(x>y)return; if(l==x&&r==y) {add_node (P,l,r,1); return; } clean_lazy (P,l,r); intMid= (l+r) >>1; if(Y<=mid) Add ((p<<1), l,mid,x,y); Else if(X>mid) Add ((p<<1)+1, mid+1, R,x,y); ElseAdd (p<<1), L,mid,x,mid), add ((p<<1)+1, mid+1, r,mid+1, y);}intAskintPintLintRintx) { if(L==R)returnTree[p]; Clean_lazy (P,L,R); intMid= (l+r) >>1; if(X<=mid)returnAsk ((p<<1), l,mid,x); returnAsk ((p<<1)+1, mid+1, r,x);}intMain () {intn=0; scanf ("%d",&N); for(intI=1; i<n;i++) { intu=0, v=0; scanf ("%d%d",&u,&v); Make_edge (U,V); Make_edge (V,u); } DFS (1,0); for(intI=1; i<=n;i++) { intx=0; scanf ("%d",&x); printf ("%d\n", Ask (1,1, n,dfn[x]));//Direct output of the right value of the destinationAdd1,1, n,dfn[x]+1, dfn[x]+size[x]-1);//adds 1 to the weight of all nodes in the subtree of the node where the current destination is located } return 0;}
Luogu P2982 [Usaco10feb] slow down slowing down | DFS sequence, segment tree