【BZOJ2809】【APIO2012】dispatching

2021-07-20 05:12

阅读:439

标签:style   root   技术   getchar   play   max   define   void   merge   

左偏树。

每个子节点维护大根堆,遍历一个儿子就往自己合并,合并发现钱不够了就删除队顶。

技术分享图片技术分享图片
//Achen
#include
#include
#include
#include
#include
#include
#include
#include
#includeconst int N=100007;
typedef long long LL;
using namespace std;
int n,root,rt[N],ch[N][2],sz[N],f[N];
LL m,v[N],cs[N],w[N],ans;

templatevoid read(T &x) {
    char ch=getchar(); x=0; T f=1;
    while(ch!=-&&(ch‘0||ch>9)) ch=getchar();
    if(ch==-) f=-1,ch=getchar();
    for(;ch>=0&&ch‘9;ch=getchar()) x=x*10+ch-0; x*=f;
}

int ecnt,fir[N],nxt[N],to[N],dis[N];
void add(int u,int v) {
    nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
}

#define lc ch[x][0]
#define rc ch[x][1]
void update(int x) { sz[x]=sz[lc]+sz[rc]+1; v[x]=v[lc]+v[rc]+cs[x];}

int merge(int x,int y) {
    if(!(x*y)) return x^y;
    if(cs[x]cs[y]) swap(x,y);
    rc=merge(rc,y);
    if(dis[lc]dis[rc]) swap(lc,rc);
    if(!rc) dis[x]=0;
    else dis[x]=dis[rc]+1;
    update(x);
    return x;
}

void dfs(int x) {
    for(int i=fir[x];i;i=nxt[i]) {
        dfs(to[i]);
        rt[x]=merge(rt[x],rt[to[i]]);
        while(v[rt[x]]>m) 
            rt[x]=merge(ch[rt[x]][0],ch[rt[x]][1]);
    }
    ans=max(ans,w[x]*sz[rt[x]]);
}

int main() {
#ifdef DEBUG
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
#endif
    read(n); read(m);
    for(int i=1;i) {
        read(f[i]);
        read(cs[i]);
        read(w[i]);
        if(!f[i]) root=i;
        else add(f[i],i);
        rt[i]=i;
        v[i]=cs[i];
        sz[i]=1; 
    }
    dfs(root);
    printf("%lld\n",ans);
    return 0;
}
View Code

 

【BZOJ2809】【APIO2012】dispatching

标签:style   root   技术   getchar   play   max   define   void   merge   

原文地址:http://www.cnblogs.com/Achenchen/p/8045741.html


评论


亲,登录后才可以留言!