Run out of the DFS sequence first. Then for asking P,k Ans=min (K,dep[p]) *s[p]+∑s[y]
Y is the point on the p subtree and satisfies the distance limit.
As long as the DFS sequence is built to persist the segment tree, you can quickly find out ∑s[y]
(right when review can persist line tree ...) When asked, because this is a tree that can be persisted, so the access to the node if it is empty to exit or it will be t.
#include <cstring>#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#defineRep (i,l,r) for (int i=l;i<=r;i++)#defineDown (i,l,r) for (int i=l;i>=r;i--)#defineCLR (x, y) memset (x,y,sizeof (×))#defineMAXN 300500#defineINF 0x7fffffff#definell Long Long#defineMM 100000007using namespacestd;structdata{intObj,pre;} E[MAXN*2];intHEAD[MAXN],L[MAXN],R[MAXN];intS[MAXN],NUM[MAXN],DEP[MAXN];introot[maxn],lc[maxn* -],rc[maxn* -];ll SUM[MAXN* -];inttot,cnt,n,mx,idx,m;intRead () {ll x=0, f=1;CharCh=GetChar (); while(!isdigit (CH)) {if(ch=='-') f=-1; Ch=GetChar ();} while(IsDigit (CH)) {x=x*Ten+ch-'0'; Ch=GetChar ();} returnx*F;}voidInsertintXinty) {e[++tot].obj=y; E[TOT].PRE=HEAD[X]; head[x]=tot;}voidDfsintUintf) {L[u]=++idx; num[idx]=u; for(intj=head[u];j;j=e[j].pre) { intv=E[j].obj; if(v==f)Continue; DEP[V]=dep[u]+1; mx=Max (Mx,dep[v]); DFS (V,U); S[u]+=s[v]+1; } R[u]=idx;}voidAddintLintRintXint&y,intValintPOS) {y=++CNT; Sum[y]=sum[x]+1ll*Val; if(L==R)return; Lc[y]=LC[X]; rc[y]=Rc[x]; intMid= (L+R)/2; if(pos<=mid) Add (L,mid,lc[x],lc[y],val,pos); ElseAdd (mid+1, R,rc[x],rc[y],val,pos);} ll ask (intLintRintXintLintR) { if(!x)return 0; if(L<=L&&R<=R)returnSum[x]; intMid= (L+R)/2; if(R<=mid)returnAsk (L,MID,LC[X],L,R); Else if(L>mid)returnAsk (mid+1, R,rc[x],l,r); Else returnAsk (L,mid,lc[x],l,mid) +ask (mid+1, r,rc[x],mid+1, R);}intMain () {n=read (); m=read (); Rep (I,1, N-1){ intX=read (), y=read (); Insert (x, y); Insert (Y,X); } DFS (1,0); Rep (I,1, n) Add (0, mx,root[i-1],root[i],s[num[i]],dep[num[i]]); Rep (I,1, M) { intX=read (), y=read (); ll ans=1ll*min (Y,dep[x]) *S[x]; intl=dep[x]+1, R=min (mx,dep[x]+y); Ans+=ask (0, Mx,root[r[x]],l,r); Ans-=ask (0, mx,root[l[x]-1],l,r); printf ("%lld\n", ans); } return 0;}
BZOJ3653: Laughing