bzoj3653 谈笑风生
dfs序,主席树水过去吧
#include <vector> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define pb push_back typedef long long LL; const int Maxn=300005; LL sum[Maxn*20],ans; int stk[Maxn],dep[Maxn],dfn[Maxn],size[Maxn],T[Maxn]; int son[Maxn*20][2],L[Maxn],R[Maxn],fa[Maxn]; int n,q,x,y,k,i,top,tim,st; bool v[Maxn]; vector <int> e[Maxn]; void dfs(){ stk[ top=1 ] =1; while (top){ x = stk[top]; if (!v[x]){ dfn[ L[x]=++tim ] = x; dep[x] = dep[fa[x]]+1; size[x] = 1; v[x] = 1; } while (!e[x].empty()){ y = e[x].back(); e[x].pop_back(); if (y==fa[x]) continue; fa[y] = x; stk[++top]=y; break; } if (stk[top]==x){ top--; R[x] = tim; if (fa[x]) size[fa[x]] += size[x]; } } } void ins(int &q,int p,int l,int r,int pos,LL val){ q = ++st; son[q][0] = son[p][0]; son[q][1] = son[p][1]; sum[q] = sum[p]+val; if (l==r) return; int mid=(l+r)>>1; if (pos<=mid) ins(son[q][0],son[p][0],l,mid,pos,val); else ins(son[q][1],son[p][1],mid+1,r,pos,val); } LL query(int p,int q,int l,int r,int pos){ if (l>pos) return 0; if (r<=pos) return sum[q]-sum[p]; int mid=(l+r)>>1; return query(son[p][0],son[q][0],l,mid,pos) + query(son[p][1],son[q][1],mid+1,r,pos); } void init(){ dfs(); for (i=1;i<=n;i++) ins(T[i],T[i-1],1,n,dep[dfn[i]],size[dfn[i]]-1); } int main(){ freopen("laugh.in","r",stdin); freopen("laugh.out","w",stdout); scanf("%d%d",&n,&q); for (i=1;i<n;i++){ scanf("%d%d",&x,&y); e[x].pb(y); e[y].pb(x); } init(); while (q--){ scanf("%d%d",&x,&k); if (dep[x]>k) ans = (LL)k*(size[x]-1); else ans = (LL)(dep[x]-1)*(size[x]-1); ans = ans+query(T[L[x]],T[R[x]],1,n,dep[x]+k); printf("%I64d\n",ans); } return 0; }