记录编号 264114 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [BZOJ3653]谈笑风生 最终得分 100
用户昵称 Gravatar神利·代目 是否通过 通过
代码语言 C++ 运行时间 11.194 s
提交时间 2016-05-27 18:07:47 内存使用 197.65 MiB
显示代码纯文本
#include<stdio.h>
#define fastcall __attribute__((optimize("-O3")))
#define IL  __inline__ __attribute__((always_inline))
#define ll long long
ll ans;
fastcall IL void in(int&x){for(x=getchar();x<48|x>57;x=getchar());x^=48;for(int tmp=getchar();47<tmp&tmp<58;tmp=getchar())x=x*10+(tmp^48);}
int n,m,k,mxdep,shu,first[300010];
struct edge{int v,nx;}o[600010];
fastcall IL void add(int u,int v){
    o[++shu].v=v,o[shu].nx=first[u],first[u]=shu;
}
int id[300010],rid[300010],s[300010],dep[300010];
fastcall inline void dfs(int x,int last){
    if(mxdep<dep[x])mxdep=dep[x];
    s[x]=1,id[x]=++id[0],rid[id[0]]=x;
    for(int i=first[x];i;i=o[i].nx)if(o[i].v!=last)
        dep[o[i].v]=dep[x]+1,dfs(o[i].v,x),s[x]+=s[o[i].v];
}
int cnt1,rt1[300010],ls1[6000010],rs1[6000010];
ll tr1[6000010];
fastcall inline void ADD1(int l,int r,int t,int tt,int x){
    tr1[t]=tr1[tt]+1;
    if(l==r)return;
    int mid=l+r>>1;
    if(x<=mid){
        if(!ls1[t])ls1[t]=++cnt1;
        rs1[t]=rs1[tt];
        ADD1(l,mid,ls1[t],ls1[tt],x);
    }else{
        if(!rs1[t])rs1[t]=++cnt1;
        ls1[t]=ls1[tt];
        ADD1(mid+1,r,rs1[t],rs1[tt],x);
    }
}
int cnt2,rt2[300010],ls2[6000010],rs2[6000010];
ll tr2[6000010];
fastcall inline void ADD2(int l,int r,int t,int tt,int x){
    tr2[t]=tr2[tt]+x;
    if(l==r)return;
    int mid=l+r>>1;
    if(x<=mid){
        if(!ls2[t])ls2[t]=++cnt2;
        rs2[t]=rs2[tt];
        ADD2(l,mid,ls2[t],ls2[tt],x);
    }else{
        if(!rs2[t])rs2[t]=++cnt2;
        ls2[t]=ls2[tt];
        ADD2(mid+1,r,rs2[t],rs2[tt],x);
    }
}
fastcall inline ll sum1(int l,int r,int t,int tt,int L,int R){
    if(L<=l&&r<=R)return tr1[t]-tr1[tt];
    int mid=l+r>>1;
    if(R<=mid)return sum1(l,mid,ls1[t],ls1[tt],L,R);
    if(L>mid)return sum1(mid+1,r,rs1[t],rs1[tt],L,R);
    return sum1(l,mid,ls1[t],ls1[tt],L,R)+sum1(mid+1,r,rs1[t],rs1[tt],L,R);
}
fastcall inline ll sum2(int l,int r,int t,int tt,int L,int R){
    if(L<=l&&r<=R)return tr2[t]-tr2[tt];
    int mid=l+r>>1;
    if(R<=mid)return sum2(l,mid,ls2[t],ls2[tt],L,R);
    if(L>mid)return sum2(mid+1,r,rs2[t],rs2[tt],L,R);
    return sum2(l,mid,ls2[t],ls2[tt],L,R)+sum2(mid+1,r,rs2[t],rs2[tt],L,R); 
}
int main(){
	freopen("laugh.in","r",stdin);
	freopen("laugh.out","w",stdout);
    in(n),in(m);
    for(int i=1,u,v;i<n;++i)
        in(u),in(v),add(u,v),add(v,u);
    dfs(1,1);
    for(int i=1;i<=n;++i)
        ADD1(0,mxdep,rt1[i]=++cnt1,rt1[i-1],dep[rid[i]]);
    for(int i=1;i<=n;++i)
        ADD2(0,mxdep,rt2[i]=++cnt2,rt2[i-1],dep[rid[i]]);
    for(int i=1,x;i<=m;++i){
        in(x),in(k);
        ans=0;
        if(k){
            ans+=sum2(0,mxdep,rt2[id[x]+s[x]-1],rt2[id[x]],dep[x]+1,dep[x]+k);
            ans-=sum1(0,mxdep,rt1[id[x]+s[x]-1],rt1[id[x]],dep[x]+1,dep[x]+k)*(dep[x]+1);   
        }
        if(dep[x]+k<mxdep)ans+=sum1(0,mxdep,rt1[id[x]+s[x]-1],rt1[id[x]],dep[x]+k+1,mxdep)*k;
        if(k>dep[x])k=dep[x];
        ans+=(ll)k*(s[x]-1);
        printf("%lld\n",ans);
    }
}