原题:APIO 2012 派遣
方法:splay 启发式合并
program dispatching;
const maxn=100000+100;
type
link=^node;node=record x:longint; next:link;end;
var
l,r,s,w,f,fa:array[1..maxn]of longint;
ge:array[1..maxn]of link;
procedure push(var x:link;const t:longint);inline;var p:link;
begin
new(p);p^.x:=t;p^.next:=x;x:=p;
end;
procedure update(const x:longint);inline;
begin
s[x]:=s[l[x]]+s[r[x]]+1;
f[x]:=f[l[x]]+f[r[x]]+w[x];
end;
procedure left(var i:longint);var j:longint;
begin
j:=r[i];r[i]:=l[j];l[j]:=i;
s[j]:=s[i];f[j]:=f[i];update(j);i:=j;
end;
procedure right(var i:longint);var j:longint;
begin
j:=l[i];l[i]:=r[j];r[j]:=i;
s[j]:=s[i];f[j]:=f[i];update(j);i:=j;
end;
procedure insert(var i:longint;const j:longint);
begin
if i=0 then begin i:=j; exit; end;
if w[j]<=w[i] then begin
insert(l[i],j);right(i);
end else begin
insert(r[i],j);left(i);
end;
end;
function union(x,y:longint):longint;
var ll,rr:longint;
begin
if (x=0)or(y=0) then exit(x+y);
if x=y then exit(x);
ll:=l[y];l[y]:=0;
rr:=r[y];r[y]:=0;
s[y]:=0; insert(x,y);
l[y]:=union(l[x],ll);
r[y]:=union(r[x],rr);
update(x);exit(x);
end;
while find(x:longint):longint;
begin
while x<>0 do begin
if s[l[x]]+1=k then exit(X);
if s[l[x]]<k then x:=l[x] else
begin dec(k,s[l[x]]); x:=r[x]; end;
end;
end;
var n,i,h,t,ans:longint; p:link;
procedure getans(const x:longint);inline;
begin if x>ans then ans:=x;end;
begin
readln(n);
for i:=1 to n do begin
readln(fa[i],w[i],l[i]);
push(ge[fa[i]],i);
end;
for i:=1 to n do begin s[i]:=1;tt[i]:=i;end;
while h<t do begin
inc(h); p:=ge[q[h]];
while p<>nil do begin
inc(t);q[t]:=p^.x;p:=p^.next;
tt[q[h]]:=union(ls[x]);
end;
end;
for i:=n downto 1 do begin
p:=ge[q[i]];while p<>nil do begin
tt[q[i]]:=union(tt[p^.x]);
x:=x^.next;end
getans(l[q[i]]*find(tt[q[i]]));
end;
end;