标签:void efi 它的 方式 code desc size 自己的 管理
Description
Solution
可并堆
枚举管理者,所能排遣的忍者在它的子树中,如果薪水超出预算就把最大的元素弹出
不断向上合并
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #define MAXN 100005 typedef long long LL; using namespace std; int n,m,b[MAXN],c[MAXN],l[MAXN],tot=0,root[MAXN]; LL ans=0; struct Node { int lch,rch,w,d,sz,sum; }heap[MAXN]; void update(int x) { heap[x].d=heap[heap[x].rch].d+1; heap[x].sz=heap[heap[x].lch].sz+heap[heap[x].rch].sz+1; heap[x].sum=heap[heap[x].lch].sum+heap[heap[x].rch].sum+heap[x].w; } int merge(int x,int y) { if(!x||!y)return x+y; if(heap[x].w<heap[y].w)swap(x,y); heap[x].rch=merge(heap[x].rch,y); if(heap[heap[x].lch].d<heap[heap[x].rch].d)swap(heap[x].lch,heap[x].rch); update(x); return x; } int insert(int w) { heap[++tot].d=0,heap[tot].sz=1; heap[tot].lch=heap[tot].rch=0; heap[tot].sum=heap[tot].w=w; return tot; } void pop(int &x) { x=merge(heap[x].lch,heap[x].rch); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d%d%d",&b[i],&c[i],&l[i]); root[i]=insert(c[i]); while(heap[root[i]].sum>m)pop(root[i]); } for(int i=n;i>0;i--) { ans=max(ans,1LL*heap[root[i]].sz*l[i]); root[b[i]]=merge(root[i],root[b[i]]); while(heap[root[b[i]]].sum>m)pop(root[b[i]]); } printf("%lld",ans); return 0; }
[BZOJ 2809][Apio2012]dispatching(左偏树)
标签:void efi 它的 方式 code desc size 自己的 管理
原文地址:http://www.cnblogs.com/Zars19/p/6765289.html