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;
}