BZOJ 3011 Running Away From the Barn

Posted on 2016-05-10 21:06  ziliuziliu  阅读(83)  评论(0编辑  收藏  举报

从下到上合并。

可并堆,显然可以打标记。

要开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\n",ans[i]);
    return 0;
}