1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| #include<iostream> #include<cstdio> #include<vector> using namespace std; long long read() { long long x=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } const long long N=300000+100; const long long M=N*30; struct SegmentTree { #define mid ((now_l+now_r)>>1) long long son[M][2],cnt; long long sum[M]; inline void update(long long now) { sum[now]=sum[son[now][0]]+sum[son[now][1]]; } void Build(long long now,long long now_l,long long now_r) { if(now_l==now_r) return; Build(son[now][0]=++cnt,now_l,mid); Build(son[now][1]=++cnt,mid+1,now_r); } void Add(long long x,long long num,long long now,long long pre,long long now_l,long long now_r) { if(now_l==now_r) { sum[now]=sum[pre]; sum[now]+=num; return ; } if(x<=mid) son[now][1]=son[pre][1],Add(x,num,son[now][0]=++cnt,son[pre][0],now_l,mid); else son[now][0]=son[pre][0],Add(x,num,son[now][1]=++cnt,son[pre][1],mid+1,now_r); update(now); } long long Query(long long L,long long R,long long now,long long pre,long long now_l,long long now_r) { if(now_l>=L and now_r<=R) return sum[now]-sum[pre]; long long ans=0; if(L<=mid) ans+=Query(L,R,son[now][0],son[pre][0],now_l,mid); if(R>mid) ans+=Query(L,R,son[now][1],son[pre][1],mid+1,now_r); return ans; } void Print(long long now,long long now_l,long long now_r) { cerr<<"no."<<now<<" now_l&r:"<<now_l<<" "<<now_r<<" sonl&r"<<son[now][0]<<" "<<son[now][1]<<" sum:"<<sum[now]<<endl; if(now_l!=now_r) { Print(son[now][0],now_l,mid); Print(son[now][1],mid+1,now_r); } } #undef mid }sgt; vector <long long> e[N]; long long n,m,depth[N],size[N],dfn[N],dfn_to,r[N]; void dfs2(long long now) { dfn[now]=++dfn_to; size[now]=1; for(long long i=0;i<(long long)(e[now].size());i++) if(depth[e[now][i]]==0) { depth[e[now][i]]=depth[now]+1; dfs2(e[now][i]); size[now]+=size[e[now][i]]; } } void dfs(long long now) { r[dfn[now]]=++sgt.cnt; sgt.Add(depth[now],size[now]-1,r[dfn[now]],r[dfn[now]-1],1,n); for(long long i=0;i<(long long)(e[now].size());i++) if(depth[e[now][i]]>depth[now]) dfs(e[now][i]); } int main() { n=read(),m=read(); for(long long i=1;i<=n;i++) e[i].reserve(4); for(long long i=1;i<n;i++) { long long s=read(),t=read(); e[s].push_back(t); e[t].push_back(s); }
sgt.Build(0,1,n); depth[1]=1; dfs2(1); dfs(1);
for(long long i=1;i<=m;i++) { long long p=read(),K=read(); long long ans=sgt.Query(depth[p]+1,depth[p]+K,r[dfn[p]+size[p]-1],r[dfn[p]-1],1,n); ans+=min(K,depth[p]-1)*(size[p]-1); printf("%lld\n",ans); } return 0; }
|