记录编号 248360 评测结果 AAAAAAAAAAAAAAWWWWWW
题目名称 [BZOJ3653]谈笑风生 最终得分 70
用户昵称 GravatarTenderRun 是否通过 未通过
代码语言 C++ 运行时间 7.174 s
提交时间 2016-04-10 13:14:19 内存使用 480.97 MiB
显示代码纯文本
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn=9000010;
int cnt,fir[maxn],nxt[maxn<<1],to[maxn<<1];
int tot,ID[maxn],end[maxn],dep[maxn],sz[maxn];
long long sum[maxn];
int ch[maxn][2],rt[maxn],maxd;
void addedge(int a,int b){
	nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=cnt;
}

void DFS(int x){
	sz[x]=1;ID[x]=++tot;maxd=max(maxd,dep[x]);
	for(int i=fir[x];i;i=nxt[i])
		if(!ID[to[i]]){
			dep[to[i]]=dep[x]+1;
			DFS(to[i]);
			sz[x]+=sz[to[i]];
		}
	end[x]=tot;	
}

queue<int>q;
int cntot=0;
void Insert(int pre,int &rt,int l,int r,int g,int d){
	rt=++cntot;
	ch[rt][0]=ch[pre][0];
	ch[rt][1]=ch[pre][1];
	sum[rt]=sum[pre]+d;
	if(l==r)return;
	int mid=(l+r)>>1;
	if(mid>=g)Insert(ch[pre][0],ch[rt][0],l,mid,g,d);
	else Insert(ch[pre][1],ch[rt][1],mid+1,r,g,d);
}

long long Query(int pre,int rt,int l,int r,int a,int b){
	if(l>=a&&r<=b)return sum[rt]-sum[pre];
	int mid=(l+r)>>1,ret=0;
	if(mid>=a)ret=Query(ch[pre][0],ch[rt][0],l,mid,a,b);
	if(mid<b)ret+=Query(ch[pre][1],ch[rt][1],mid+1,r,a,b);	
	return ret;
}
int main(){
	freopen("laugh.in","r",stdin);
	freopen("laugh.out","w",stdout);
	int n,Q;
	scanf("%d%d",&n,&Q);
	for(int i=1,a,b;i<n;i++){
		scanf("%d%d",&a,&b);
		addedge(a,b);
		addedge(b,a);
	}
	dep[1]=1;
	DFS(1);
	q.push(1);
	while(!q.empty()){
		int x=q.front();q.pop();
		for(int i=fir[x];i;i=nxt[i])
			if(dep[to[i]]==dep[x]+1){
				if(rt[dep[to[i]]])
					Insert(rt[dep[to[i]]],rt[dep[to[i]]],1,n,ID[to[i]],sz[to[i]]-1);
				else
					Insert(rt[dep[x]],rt[dep[to[i]]],1,n,ID[to[i]],sz[to[i]]-1);
				q.push(to[i]);
			}	
	}
	int a,k;
	long long ans;
	while(Q--){
		scanf("%d%d",&a,&k);
		ans=1ll*min(dep[a]-1,k)*(sz[a]-1ll);
		ans+=Query(rt[dep[a]],rt[min(dep[a]+k,maxd)],1,n,ID[a],end[a]);
		printf("%lld\n",ans);
	}	
	return 0;
}