Test instructions
Give a tree with a root at point 1th, and ask how many points in the subtree of each point have a point less than or equal to L .
n<=200000;
Exercises
This question is more interesting;
The first consideration is the tree DP, but the DP is completely unable to transfer;
Consider the answer to a knot, which is the number of points (nonsense) in the subtree that is less than or equal to the node distance.
What about the answer of his father in this subtree?
The distance of each point in the subtree increases, and the relative size relationship does not change;
So we use a can and heap to maintain the subtree, each time the heap in the distance too large point pops out;
The length of the heap is directly from this point to the length of 1, and the distance to the current sub-tree root is subtracted from the length of the subtree to 1;
Then the size of the heap is counted, and then the heap is merged upward;
Time complexity is O (nlogn), sweep once the tree is out of the solution;
What if Benquan negative?
Each point may be added to the heap more than once, but it is wrong to make a heap complexity on the top;
So on the heuristic merging the balance tree = =,o (nlog^2n) solved;
Code:
#include <queue> #include <stdio.h> #include <string.h> #include <algorithm> #define N 210000using namespace Std;typedef Long long ll;int ch[n][2],dis[n],size[n];int out[n],fa[n],root[n],ans[n];ll l[n]; queue<int>q;void pushup (int x) {size[x]=size[ch[x][0]]+size[ch[x][1]]+1;} int merge (int x,int y) {if (!x| |! Y) return x+y;if (L[x]<l[y]) swap (x, y), Ch[x][1]=merge (ch[x][1],y); Pushup (x), if (dis[ch[x][0]]<dis[ch[x][1]) swap (ch[x][0],ch[x][1]);d Is[x]=dis[ch[x][1]]+1;return x;} int main () {int n,i,j,k,x,y;ll m;scanf ("%d%lld", &n,&m);d is[0]=-1,size[1]=1,root[1]=1;for (i=2;i<=n;i++) { scanf ("%d%lld", fa+i,l+i); out[fa[i]]++,size[i]=1,root[i]=i; L[i]+=l[fa[i]];} for (i=1;i<=n;i++) {if (out[i]==0) Q.push (i);} Out[0]++;while (!q.empty ()) {X=q.front (), Q.pop (), while (l[root[x]]-l[x]>m) Root[x]=merge (ch[root[x]][0],ch[root [X]] [1]); Ans[x]=size[root[x]];y=fa[x];root[y]=merge (Root[y],root[x]); Out[y]--;if (!out[y]) Q.push (y);} for (i=1;i<=n;i++) printf ("%d\n", Ans[i]); return 0;}
bzoj-3011 Running away from the Barn