斜堆与左偏树

2809的dipatching是一道很SB的题啊。
实际上就是在以某一个节点x为根的子树中选一些点,使得sigma(salary.i)<=m的前提下lead.x*num最大(num为选的点个数)。
题意很好理解,思路也很好想,维护一个类似堆的东西,dfs时要支持合并,超过m之后要删除最大元素。
无聊就用了两种方法写,左偏树和斜堆,算作练习。

斜堆

总结起来斜堆是个很SB的东西,什么都不用维护直接最后swap左右儿子。均摊log
/**************************************************************
    Problem: 2809
    User: liuxin
    Language: Pascal
    Result: Accepted
    Time:2060 ms
    Memory:5516 kb
****************************************************************/

type
    Edge=record
        ed,nt:array[0..200005]of longint;
        lt:array[0..100005]of longint;
        l:longint;
    end;
    Node=record l,r,v:longint; end;
var
    E:Edge;
    ans:int64;
    i,k,n,m,cnt:longint;
    h:array[0..100005]of Node;
    heap,size,lead,cap,num:array[0..100005]of longint;

    procedure swap(var i,j:longint);var k:longint; begin k:=i; i:=j; j:=k; end;
    function merge(p,q:longint):longint;
    begin
        if (p=0) then exit(q) else if (q=0) then exit(p);
        if (h[p].v<h[q].v) then swap(p,q);
        h[p].r:=merge(h[p].r,q); swap(h[p].l,h[p].r); exit(p);
    end;
    procedure dfs(x:longint);
    var i,y:longint;
    begin
        cap[x]:=size[x]; num[x]:=1; i:=E.lt[x];
        inc(cnt); heap[x]:=cnt; h[cnt].l:=0; h[cnt].r:=0; h[cnt].v:=size[x];
        while (i>0) do begin
            y:=E.ed[i]; dfs(y);
            cap[x]:=cap[x]+cap[y]; num[x]:=num[x]+num[y];
            heap[x]:=merge(heap[x],heap[y]);
            while (cap[x]>m) do begin
                cap[x]:=cap[x]-h[heap[x]].v; dec(num[x]);
                heap[x]:=merge(h[heap[x]].l,h[heap[x]].r);
            end;
            i:=E.nt[i];
        end;
        if (int64(num[x])*lead[x]>ans) then ans:=int64(num[x])*lead[x];
    end;
    procedure add(x,y:longint);
    begin inc(E.l); E.ed[E.l]:=y; E.nt[E.l]:=E.lt[x]; E.lt[x]:=E.l; end;

begin
    readln(n,m); E.l:=0; ans:=0;
    for i:=1 to n do begin
        readln(k,size[i],lead[i]);
        if (k>0) then add(k,i);
    end;
    dfs(1); writeln(ans);
end.

左偏树

左偏树看起来科学一点,有严格的证明,多维护了一个东西感觉不错。严格log
/**************************************************************
    Problem: 2809
    User: liuxin
    Language: Pascal
    Result: Accepted
    Time:2364 ms
    Memory:8324 kb
****************************************************************/

type
    Node=^HeapNode;
    HeapNode=record
        key,dis:int64;
        l,r:Node;
    end;
    Edge=record
        l:longint;
        ed,nt,lt:array[0..100005]of longint;
    end;
var
    E:Edge;
    Null:Node;
    ans:int64;
    i,k,n,m,root:longint;
    H:array[0..100005]of Node;
    salary,lead,num,sum:array[0..100005]of int64;

    function Newnode(k:longint):Node; var tmp:Node;
    begin new(tmp); tmp^.l:=Null; tmp^.r:=Null; tmp^.key:=k; tmp^.dis:=1; exit(tmp); end;
    function Merge(x,y:Node):Node;
    var tmp:Node;
    begin
        if (x=Null) then exit(y);
        if (y=Null) then exit(x);
        if (x^.key<y^.key) then begin tmp:=x; x:=y; y:=tmp; end;
        x^.r:=Merge(x^.r,y);
        if (x^.r^.dis>x^.l^.dis) then begin tmp:=x^.r; x^.r:=x^.l; x^.l:=tmp; end;
        x^.dis:=x^.r^.dis+1; exit(x);
    end;
    procedure dfs(t:longint);
    var i,j:longint;
    begin
        num[t]:=1; sum[t]:=salary[t]; H[t]:=Newnode(salary[t]); i:=E.lt[t];
        while (i>0) do begin
            j:=E.ed[i]; dfs(j); 
            num[t]:=num[t]+num[j]; sum[t]:=sum[t]+sum[j]; H[t]:=Merge(H[t],H[j]); 
            i:=E.nt[i];
        end;
        while (sum[t]>m) do
            begin dec(num[t]); dec(sum[t],H[t]^.key); H[t]:=Merge(H[t]^.l,H[t]^.r); end;
        if (ans<num[t]*lead[t]) then ans:=num[t]*lead[t];
    end;
    procedure add(x,y:longint);
    begin inc(E.l); E.ed[E.l]:=y; E.nt[E.l]:=E.lt[x]; E.lt[x]:=E.l; end;

begin
    readln(n,m);
    fillchar(E.lt,sizeof(E.lt),0); E.l:=0;
    for i:=1 to n do begin
        readln(k,salary[i],lead[i]); 
        if (k=0) then root:=i else add(k,i);
    end;
    new(Null); Null^.key:=0; Null^.dis:=0; Null^.l:=Null; Null^.r:=Null;
    ans:=0; dfs(root); writeln(ans);
end.
购物商城项目采用PHP+mysql有以及html+css jq以及layer.js datatables bootstorap等插件等开发,采用了MVC模式,建立一个完善的电商系统,通过不同用户的不同需求,进行相应的调配和处理,提高对购买用户进行配置….zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值