【BZOJ 3011】[Usaco2012 Dec]Running Away From the Barn 可并堆

来源:互联网 发布:淘宝多口袋工装休闲裤 编辑:程序博客网 时间:2024/06/05 08:14

类似于BZOJ2809的做法,直接合并可并堆就ok了,区别可能就在于多了一个lazy标记吧,记得下放就没什么了,但是。。。。

坑:1.是找<=L的点不是小于(这个可以通过样例看出来)

       2.开long long(wa了多少发啊,最后一气之下,直接替换)

#include<cstdio>#include<cstring>#include<iostream>#define LL long long#define maxn 500021using namespace std;int n,head[maxn],tot=1,ans[maxn],rt[maxn];LL m;struct edge{int v,next;LL w;}e[maxn*2];void adde(int a,int b,LL c){e[tot].v=b,e[tot].next=head[a],e[tot].w=c;head[a]=tot++;}struct lTree{int rs[maxn],ls[maxn],d[maxn],size[maxn];LL val[maxn],lz[maxn];void push_down(int u){if(!lz[u])return;val[ls[u]]+=lz[u],lz[ls[u]]+=lz[u];val[rs[u]]+=lz[u],lz[rs[u]]+=lz[u];lz[u]=0;}int merge(int a,int b){if(!a||!b)return a+b;if(val[a]<val[b])swap(a,b);push_down(a);rs[a]=merge(rs[a],b);if(d[rs[a]]>d[ls[a]])swap(ls[a],rs[a]);d[a]=d[rs[a]]+1;size[a]=size[ls[a]]+size[rs[a]]+1;return a;}int pop(int u){push_down(u);return merge(ls[u],rs[u]);}LL top(int u){return val[u];}int Q(int u){return size[u];}}q;void dfs(int u){q.size[u]=1,rt[u]=u;for(int v,i=head[u];i;i=e[i].next){v=e[i].v;dfs(v);q.lz[rt[v]]+=e[i].w,q.val[rt[v]]+=e[i].w;rt[u]=q.merge(rt[u],rt[v]);}while(q.top(rt[u])>m)rt[u]=q.pop(rt[u]);ans[u]=q.Q(rt[u]);}int main(){scanf("%d%lld",&n,&m);LL c;for(int a,b,i=2;i<=n;i++){scanf("%d%lld",&a,&c);adde(a,i,c);}dfs(1);for(int i=1;i<=n;i++)printf("%d\n",ans[i]);return 0;}



0 0