FlappyBear @ 2019-01-09 21:36:02
为什么自己写的和标程100000级别对拍一晚上没错,交上来却爆0/:v:/
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
long long n,q,nex[650000],fir[650000],to[650000],tot,tot1,T[350000];
long long dep[350000],la_num[350000],st_num[350000],Max_dep,size[350000];
long long find_ans(long long last,long long pos,long long l,long long r,long long place);
void dfs2(long long x,long long fa);
long long update(long long last,long long l,long long r,long long place,long long w);
void Update(long long x);
long long build(long long l,long long r);
void dfs1(long long x,long long fa);
struct node{
long long ls,rs;
long long value;
}s[300300*20];
//此题按照dfn序为顺序建立主席树,查询答案时直接树相减即可
int main()
{
freopen("rand","r",stdin);
freopen("0.pts","w",stdout);
cin>>n>>q;
for(long long i=1;i<n;i++)
{
long long u,v;
scanf("%lld%lld",&u,&v);
nex[++tot]=fir[u];fir[u]=tot;to[tot]=v;
nex[++tot]=fir[v];fir[v]=tot;to[tot]=u;
}
dfs1(1,0);//处理size和dep
T[0]=build(1,Max_dep);
dfs2(1,0);
for(long long i=q;i;i--)
{
long long ans=0;
long long x,k;
scanf("%lld%lld",&x,&k);
ans+=min(dep[x]-1,k)*(size[x]-1);
if(st_num[x]<=la_num[x])
ans+=find_ans(T[st_num[x]-1],T[la_num[x]],1,Max_dep,dep[x]+k);
printf("%lld\n",ans);
}
return 0;
}
long long find_ans(long long last,long long pos,long long l,long long r,long long place)//No Problem
{
if(l==r)
return s[pos].value-s[last].value;
long long mid=l+r>>1;
if(place>mid)
return find_ans(s[last].rs,s[pos].rs,mid+1,r,place)+s[s[pos].ls].value-s[s[last].ls].value;
return find_ans(s[last].ls,s[pos].ls,l,mid,place);
}
void dfs2(long long x,long long fa)//No Problem
{
T[++tot1]=update(T[tot1-1],1,Max_dep,dep[x],size[x]-1);
st_num[x]=tot1+1;//子树入边
for(long long e=fir[x];e;e=nex[e])
{
long long v=to[e];
if(v==fa)
continue;
dfs2(v,x);
}
la_num[x]=tot1;//子树出边
return;
}
long long update(long long last,long long l,long long r,long long place,long long w)//No Problem
{
long long pos=++tot;
if(l==r)
{
s[pos].value=s[last].value+w;
return pos;
}
s[pos].ls=s[last].ls;
s[pos].rs=s[last].rs;
long long mid=l+r>>1;
if(place<=mid)
s[pos].ls=update(s[last].ls,l,mid,place,w);
else
s[pos].rs=update(s[last].rs,mid+1,r,place,w);
Update(pos);
return pos;
}
void Update(long long x)//No Problem
{
s[x].value=s[s[x].ls].value+s[s[x].rs].value;
return;
}
long long build(long long l,long long r)//No Problem
{
long long pos=++tot;
if(l==r)
return pos;
long long mid=l+r>>1;
s[pos].ls=build(l,mid);
s[pos].rs=build(mid+1,r);
return pos;
}
void dfs1(long long x,long long fa)//No Problem
{
dep[x]=dep[fa]+1;
Max_dep=max(Max_dep,dep[x]);
size[x]=1;
for(long long e=fir[x];e;e=nex[e])
{
long long v=to[e];
if(v==fa)
continue;
dfs1(v,x);
size[x]+=size[v];
}
return;
}
by FlappyBear @ 2019-01-09 21:37:00
删掉freopen也没有用/:v:/