ORZ blutrex。。。。。。
主席树。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 1000500 #define maxq 1000500 #define maxe 1600500 using namespace std; struct edge { long long v,nxt; }e[maxe]; struct answer { long long sum1,sum2; }; long long n,q,x,y,nume=0,g[maxv],size[maxv],dis[maxv],w[maxv],mx[maxv],mxdis=0,cnt=0,fw[maxv]; long long root[maxv],ls[maxv<<3],rs[maxv<<3],val1[maxv<<3],val2[maxv<<3],tot=0; void addedge(long long u,long long v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } void dfs(long long x,long long fath) { size[x]=1;w[x]=++cnt;mx[x]=w[x];fw[cnt]=x; for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; if (v!=fath) { dis[v]=dis[x]+1;mxdis=max(mxdis,dis[v]); dfs(v,x); size[x]+=size[v]; mx[x]=max(mx[x],mx[v]); } } } void build(long long &now,long long left,long long right) { now=++tot;val1[now]=val2[now]=0; if (left==right) return; long long mid=(left+right)>>1; build(ls[now],left,mid); build(rs[now],mid+1,right); } void modify(long long last,long long &now,long long left,long long right,long long pos,long long x) { now=++tot;ls[now]=ls[last];rs[now]=rs[last]; val1[now]=val1[last]+x;val2[now]=val2[last]+1; if (left==right) return; long long mid=(left+right)>>1; if (pos<=mid) modify(ls[last],ls[now],left,mid,pos,x); else modify(rs[last],rs[now],mid+1,right,pos,x); } answer merge(answer x,answer y) { answer ret; ret.sum1=x.sum1+y.sum1; ret.sum2=x.sum2+y.sum2; return ret; } answer ask(long long last,long long now,long long left,long long right,long long l,long long r) { answer ret; if ((left==l) && (right==r)) { ret.sum1=val1[now]-val1[last]; ret.sum2=val2[now]-val2[last]; return ret; } long long mid=(left+right)>>1; if (r<=mid) return ask(ls[last],ls[now],left,mid,l,r); else if (l>=mid+1) return ask(rs[last],rs[now],mid+1,right,l,r); else return merge(ask(ls[last],ls[now],left,mid,l,mid),ask(rs[last],rs[now],mid+1,right,mid+1,r)); } int main() { scanf("%lld%lld",&n,&q); for (long long i=1;i<=n-1;i++) { scanf("%lld%lld",&x,&y); addedge(x,y); addedge(y,x); } dfs(1,1); build(root[0],0,mxdis); for (long long i=1;i<=n;i++) modify(root[i-1],root[i],0,mxdis,dis[fw[i]],size[fw[i]]); for (long long i=1;i<=q;i++) { scanf("%lld%lld",&x,&y); long long ret=min(dis[x],y)*(size[x]-1); answer regis=ask(root[w[x]-1],root[mx[x]],0,mxdis,min(dis[x]+1,mxdis),min(dis[x]+y,mxdis)); ret+=regis.sum1-regis.sum2; printf("%lld\n",ret); } return 0; }