BZOJ 2809 dispatching

Posted on 2016-05-07 11:44  ziliuziliu  阅读(116)  评论(0编辑  收藏  举报

APIO题。。。我是拿左偏树做的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxv 100500
#define maxe 100500
using namespace std;
long long n,m,tree[maxv][3],fath[maxv],g[maxv],nume=0,size[maxv],val[maxv],dis[maxv];
long long a,b,c,w[maxv],q[maxv],ans=0,top[maxv];
struct edge
{
    long long v,nxt;
}e[maxe];
void addedge(long long u,long long v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void pushup(long long x)
{
    long long ls=tree[x][1],rs=tree[x][2];
    if (dis[ls]<dis[rs]) swap(tree[x][1],tree[x][2]);
    if (rs==0) dis[x]=0;
    else dis[x]=dis[rs]+1;
    size[x]=size[ls]+size[rs]+1;
    val[x]=val[ls]+val[rs]+w[x];
}
long long merge(long long a,long long b)
{
    if (a==0) return b;
    if (b==0) return a;
    if (w[a]<w[b]) swap(a,b);
    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];
    fath[ls]=ls;fath[rs]=rs;
    tree[x][1]=0;tree[x][2]=0;size[x]=1;val[x]=w[x];dis[x]=0;
    return merge(ls,rs);
}
void dfs(long long now)
{
    long long regis=now;
    for (long long i=g[now];i;i=e[i].nxt)
    {
        long long v=e[i].v;
        dfs(v);
    }
    for (long long i=g[now];i;i=e[i].nxt)
    {
        long long v=e[i].v;
        regis=merge(regis,top[v]);
    }
    while (val[regis]>m) 
        regis=pop(regis);
    top[now]=regis;
    ans=max(ans,size[regis]*q[now]);
}
int main()
{
    scanf("%lld%lld",&n,&m);
    for (long long i=1;i<=n;i++)
    {
        scanf("%lld%lld%lld",&a,&b,&c);
        if (a) addedge(a,i);
        w[i]=b;q[i]=c;
    }
    for (long long i=1;i<=n;i++) 
    {
        fath[i]=i;
        val[i]=w[i];
        size[i]=1;
        top[i]=i;
    }
    dfs(1);
    printf("%lld\n",ans);
    return 0;
}