vijos 不差钱 sbt的运用

 

不差钱

Buchaqian.pas

描述:

同学们一起看了小品《不差钱》,LX神突发奇想,想刁难一下十八居士,他让十八居士模拟一下点菜的过程。

输入:

第一行为一个数price,表示价钱大于price的菜赵本山都不要。

以下几行表示点菜的过程,每行两个整数pn

p=1 表示在菜谱中添加一个价格为n的菜,这是第i1号命令,这个菜的编号就是i

p=2 表示菜谱中第n号菜已卖完(但不代表菜谱中没有了这种菜),

p=3 表示赵本山点第n贵的菜。

输入文件以0结束。

菜的价格0

3种命令,

30%数据命令最多300次,

60%数据命令最多3000次,

100%数据命令最多100000次。

输出:

对于每个p=3

如果第n贵的菜价格高于price,则输出“Dui bu qi,Mei you.”。

如果第n贵的菜价格不高于price,且没有卖完,则输出“You.”然后输出价格m Yuan

如果已卖完,则输出“Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!

分析:由于命令数最多有100000次,用桶、归并排序均会超时。可以用平衡二叉树来解决,我选择的是sbt。对于每一道菜,将价格作为关键字插入sbt中,用一个桶a记录某价格的菜有多少个(有些菜价格相同)。对于询问,用sbt可以在O(logn)时间复杂度内找到第k大数,然后按照题意进行对应的判断即可。

代码:

const maxn=100000; var max,tt,x,y:longint; key,s,l,r:array[0..maxn] of longint; a:array[0..1000000] of longint; procedure main; var t,k:longint; procedure right_rotate(var t:longint); begin k:=l[t]; l[t]:=r[k]; r[k]:=t; s[k]:=s[t]; s[t]:=s[l[t]]+s[r[t]]+1; t:=k; end; procedure left_rotate(var t:longint); begin k:=r[t]; r[t]:=l[k]; l[k]:=t; s[k]:=s[t]; s[t]:=s[l[t]]+s[r[t]]+1; t:=k; end; procedure maintain(var t:longint;flag:boolean); begin if not flag then if s[l[l[t]]]>s[r[t]] then right_rotate(t) else if s[r[l[t]]]>s[r[t]] then begin left_rotate(l[t]); right_rotate(t); end else exit else if s[r[r[t]]]>s[l[t]] then left_rotate(t) else if s[l[r[t]]]>s[l[t]] then begin right_rotate(r[t]); left_rotate(t); end else exit; maintain(l[t],false); maintain(r[t],true); maintain(t,true); maintain(t,false); end; procedure insert(var t,v:longint); begin if t=0 then begin inc(tt); t:=tt; s[t]:=1; l[t]:=0; r[t]:=0; key[t]:=v; end else begin inc(s[t]); if v=key[t]); end; end; function select(var t:longint;k:longint):longint; begin if s[l[t]]+1=k then exit(t) else if s[l[t]]>=k then exit(select(l[t],k)) else exit(select(r[t],k-s[l[t]]-1)); end; begin readln(max); t:=0; tt:=0; read(x); while x<>0 do begin readln(y); case x of 1:begin insert(t,y); inc(a[y]); end; 2:dec(a[key[y]]); 3:begin k:=select(t,tt-y+1); if key[k]>max then writeln('Dui bu qi,Mei you.') else if a[key[k]]<=0 then writeln('Mei you. Zhe ge ke yi you. Zhe ge zhen mei you!') else writeln('You.',key[k],' Yuan.'); end; end; read(x); end; end; begin main; end.

你可能感兴趣的:(解题报告)