超市market(堆维护,小根堆+大根堆)

来源:互联网 发布:网络运营职责 编辑:程序博客网 时间:2024/06/11 18:46

超市
(market.pas/c/cpp)
【题目描述】
超市正在举行一个活动,该活动的规则如下:
想要参与的顾客会将他购物的账单放入纸箱中,账单上写有顾客的联系方式和购物的金额。每天超市关门前纸箱中金额最大、最小的两张帐单被取出,付款金额最大的顾客将获得一笔奖金,价值为取出的两张帐单的金额之差;为了不重复计算,取出的两张帐单不再放回箱子,而剩下的帐单仍保留在箱中,进行第二天的活动。
顾客很多,因此可假定:每天活动结束时,箱中至少有两张帐单以供取出。
小h也参加了这次活动,他想知道整个活动期间超市付出的奖金总额是多少?
【输入数据】
第一行是一个整数n,表示活动历时的天数。
以下的n行,每行包含若干由空格分隔的非负整数。第i+1行的数表示在第i天投入箱子的账单金额。每行的第一个数是一个整数k,表示当日账单的数目。后面的k个正整数代表这k笔账单的金额。
【输出数据】
输出一个数,表示活动期间超市付出的奖金总额。
【样例输入】
5
3 1 2 3
2 1 1
4 10 5 5 1
0
1 2
【样例输出】
19
【数据范围】
设s为整个活动中涉及到的账单笔数。
30%的数据满足n≤100,s≤10000。
70%的数据满足s≤10^5。
100%的数据满足1≤n≤5000,0≤k≤10^5,s≤10^6,每笔账单的金额不超过10^6。

program df;
var i,j,n,m,x,y,z,k,t,len,ls:longint;
s:int64;
a,b,c,d,f:array[0..1000000] of longint;
procedure put1(x:longint);
var i,j,dd:longint;
begin
inc(len);
a[len]:=x;
i:=len;
while (i>1) and (a[i div 2]>a[i]) do
begin
dd:=a[i]; a[i]:=a[i div 2]; a[i div 2]:=dd;
i:=i div 2;
end;
end;

procedure put2(x:longint);
var i,j,dd:longint;
begin
inc(ls);
b[ls]:=x;
i:=ls;
while (i>1) and (b[i]>b[i div 2]) do
begin
dd:=b[i]; b[i]:=b[i div 2]; b[i div 2]:=dd;
i:=i div 2;
end;
end;

function get1:longint;
var i,j,m,dd:longint;
begin
get1:=a[1];
a[1]:=a[len];
dec(len);
i:=1;
while i*2<=len do
begin
if (i*2+1>len) or (a[i*2+1]>a[i*2]) then j:=i*2
else j:=i*2+1;
if a[i]>a[j] then
begin
dd:=a[j]; a[j]:=a[i]; a[i]:=dd;
end;
i:=j;
end;
end;

function get2:longint;
var i,j,m,dd:longint;
begin
get2:=b[1];
b[1]:=b[ls];
dec(ls);
i:=1;
while i*2<=ls do
begin
if (i*2+1>ls) or (b[i*2]>b[i*2+1]) then j:=i*2
else j:=i*2+1;
if b[j]>b[i] then
begin
dd:=b[j]; b[j]:=b[i]; b[i]:=dd;
end;
i:=j;
end;
end;

begin
assign(input,’market.in’);
reset(input);
assign(output,’market.out’);
rewrite(output);
readln(n);
for i:=1 to n do
begin
read(x);
for j:=1 to x do
begin
read(z);
if f[z]=0 then
begin
put1(z); //小根堆
put2(z); //大根堆
end;
inc(f[z]); //记录该数出现次数
end;
while (f[b[1]]=0) and (ls>0) do x:=get2; //次数为零的删掉
s:=s+b[1];
dec(f[b[1]]);
while (f[a[1]]=0) and (len>0) do x:=get1; //同上
s:=s-a[1];
dec(f[a[1]]);
end;
writeln(s);
close(input);
close(output);
end.

0 0