noi2004 郁闷的出纳员

用SBT神树做的,开始select居然打错了,maintain里就、自己没分清左右,树转烂了,无语。

外边有一个工资总标记量就行了。

View Code
  1 program cashier(input,output);
  2 const
  3    oo = 9999999;
  4 var
  5    left,right,keys,s : array[0..200000] of longint;
  6    money         : longint;
  7    n,tot,root         : longint;
  8    answer         : longint;
  9    minmoney         : longint;
 10 procedure left_rotate(var t: longint );
 11 var
 12    k : longint;
 13 begin
 14    k:=right[t];
 15    right[t]:=left[k];
 16    left[k]:=t;
 17    s[k]:=s[t];
 18    s[t]:=s[left[t]]+s[right[t]]+1;
 19    t:=k;
 20 end; { left_rotate }
 21 procedure right_rotate(var t :longint );
 22 var
 23    k : longint;
 24 begin
 25    k:=left[t];
 26    left[t]:=right[k];
 27    right[k]:=t;
 28    s[k]:=s[t];
 29    s[t]:=s[left[t]]+s[right[t]]+1;
 30    t:=k;
 31 end; { right_rotate }
 32 procedure maintain(var t : longint;flag:boolean );
 33 begin
 34    if not flag then
 35    begin
 36       if s[left[left[t]]]>s[right[t]] then
 37      right_rotate(t)
 38       else
 39      if s[right[left[t]]]>s[right[t]] then
 40      begin
 41         left_rotate(left[t]); //错误点
 42         right_rotate(t);
 43      end
 44      else
 45         exit;
 46    end
 47    else
 48       if s[right[right[t]]]>s[left[t]] then
 49      left_rotate(t)
 50       else
 51      if s[left[right[t]]]>s[left[t]] then
 52      begin
 53         right_rotate(right[t]);
 54         left_rotate(t);
 55      end
 56      else
 57         exit;
 58    maintain(left[t],false);
 59    maintain(right[t],true);
 60    maintain(t,false);
 61    maintain(t,true);
 62 end; { maintain }
 63 procedure insect(var now : longint; k:longint );
 64 begin
 65    if now=0 then
 66    begin
 67       inc(tot);
 68       now:=tot;
 69       left[now]:=0;
 70       right[now]:=0;
 71       s[now]:=1;
 72       keys[now]:=k;
 73    end
 74    else
 75    begin
 76       inc(s[now]);
 77       if k>=keys[now] then
 78      insect(right[now],k)
 79       else
 80      insect(left[now],k);
 81       maintain(now,k>=keys[now]);
 82    end;
 83 end; { insect }
 84 function select(now,k :longint ):longint;
 85 begin
 86    if k=s[left[now]]+1 then
 87       exit(keys[now]);
 88    if k<=s[left[now]] then  //错误点
 89       select:=select(left[now],k)
 90    else
 91       select:=select(right[now],k-s[left[now]]-1);
 92 end; { select }
 93 function delete(var now    : longint;k:longint ):longint;
 94 begin
 95    dec(s[now]);
 96    if (k=keys[now])or((k<keys[now])and(left[now]=0))or((k>=keys[now])and(right[now]=0)) then
 97    begin
 98       delete:=keys[now];
 99       if (left[now]=0)or(right[now]=0) then
100      now:=left[now]+right[now]
101       else
102      keys[now]:=delete(left[now],keys[now]+1);
103    end
104    else
105       if k<keys[now] then
106      delete:=delete(left[now],k)
107       else
108      delete:=delete(right[now],k);
109 end; { delete }
110 function getmin(now :longint ):longint;
111 begin
112    if now=0 then
113       exit(oo);
114    getmin:=getmin(left[now]);
115    if getmin=oo then
116       exit(keys[now]);
117 end; { getmin }
118 procedure main;
119 var
120    i,x : longint;
121    ch  : char;
122    tmp : longint;
123 begin
124    root:=0;
125    tot:=0;
126    fillchar(left,sizeof(left),0);
127    fillchar(right,sizeof(right),0);
128    fillchar(keys,sizeof(keys),0);
129    fillchar(s,sizeof(s),0);
130    answer:=0;
131    money:=0;
132    readln(n,minmoney);
133    for i:=1 to n do
134    begin
135       read(ch);
136       case ch of
137     'I' : begin
138        readln(x);
139        if x<minmoney then
140           continue
141        else
142           insect(root,x-money);
143     end;
144     'A' : begin
145        readln(x);
146        money:=money+x;
147     end;
148     'S' : begin
149        readln(x);
150        dec(money,x);
151        tmp:=getmin(root);
152        while (tmp+money<minmoney)and(s[root]>0) do
153        begin
154           inc(answer);
155           delete(root,tmp);
156           tmp:=getmin(root);
157        end;
158     end;
159     'F' : begin
160        readln(x);
161        if x>s[root] then
162           writeln(-1)
163        else
164           writeln(select(root,s[root]-x+1)+money);
165     end;
166       end; { case }
167    end;
168    writeln(answer);
169 end; { main }
170 begin
171    assign(input,'cashier.in');reset(input);
172    assign(output,'cashier.out');rewrite(output);
173    main;
174    close(input);
175    close(output);
176 end.
posted @ 2012-04-16 20:02  Codinginging  阅读(452)  评论(0编辑  收藏  举报