从下到上合并。
可并堆,显然可以打标记。
要开LONG LONG不然WA得很爽。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 200500 #define maxe 200500 using namespace std; struct edge { long long v,w,nxt; }e[maxe]; long long nume=0,g[maxv],n,l,x,y,w; long long tree[maxv][3],size[maxv],val[maxv],lazy[maxv]; long long ans[maxv],top[maxv],dis[maxv]; void addedge(long long u,long long v,long long w) { e[++nume].v=v; e[nume].w=w; e[nume].nxt=g[u]; g[u]=nume; } void pushdown(long long x) { if (lazy[x]) { long long ls=tree[x][1],rs=tree[x][2]; if (ls) {lazy[ls]+=lazy[x];val[ls]+=lazy[x];} if (rs) {lazy[rs]+=lazy[x];val[rs]+=lazy[x];} lazy[x]=0; } } void pushup(long long x) { if (dis[tree[x][1]]<dis[tree[x][2]]) swap(tree[x][1],tree[x][2]); long long ls=tree[x][1],rs=tree[x][2]; if (rs==0) dis[x]=0; else dis[x]=dis[rs]+1; size[x]=size[ls]+size[rs]+1; } long long merge(long long a,long long b) { if (a==0) return b; if (b==0) return a; if (val[a]<val[b]) swap(a,b); pushdown(a); tree[a][2]=merge(tree[a][2],b); pushup(a); return a; } long long pop(long long x) { long long ls=tree[x][1],rs=tree[x][2]; tree[x][1]=0;tree[x][2]=0; return merge(ls,rs); } void dfs(long long x) { long long root=x; for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; dfs(v); } for (long long i=g[x];i;i=e[i].nxt) { long long v=e[i].v; lazy[top[v]]+=e[i].w;val[top[v]]+=e[i].w; root=merge(root,top[v]); } while (val[root]>l) root=pop(root); top[x]=root;ans[x]=size[root]; } int main() { scanf("%lld%lld",&n,&l); for (long long i=1;i<=n;i++) size[i]=1; for (long long i=2;i<=n;i++) { scanf("%lld%lld",&x,&y); addedge(x,i,y); } dfs(1); for (long long i=1;i<=n;i++) printf("%lld ",ans[i]); return 0; }