花了一上午大概复习了一下splay,treap

像这种裸的数据结构题在js应该会越来越少

不过练练手也好,

这就是平衡树+hash,如果这是单纯的BST应用,还是写treap吧,好调试

  1 const rd=250008;
  2       ran=10000007;
  3 
  4 type link=^node;
  5      node=record
  6        st:string[11];
  7        loc:longint;
  8        next:link;
  9      end;
 10 
 11 var hash:array[0..rd] of link;
 12     son:array[0..300000,0..2] of longint;
 13     score,fa,count,key:array[0..300010] of longint;
 14     na:array[0..300010] of string[11];
 15     t,tot,root,x,y,i,n:longint;
 16     what,ch:char;
 17     s,ss:string;
 18 
 19 procedure update(x:longint);
 20   begin
 21     count[x]:=count[son[x,1]]+count[son[x,2]]+1;
 22   end;
 23 
 24 procedure clear(x:longint);
 25   begin
 26     count[x]:=1;
 27     fa[x]:=0;
 28     score[x]:=0;
 29     key[x]:=0;
 30     son[x,1]:=0;
 31     son[x,2]:=0;
 32     fa[0]:=0;
 33     count[0]:=0;
 34   end;
 35 
 36 function tran(x:string):longint;
 37   var l,i:longint;
 38   begin
 39     l:=length(x);
 40     tran:=0;
 41     for i:=1 to l do
 42       tran:=tran*10+ord(x[i])-48;
 43   end;
 44 
 45 function get(x:string):longint;
 46   var l,i,s:longint;
 47       p:link;
 48   begin
 49     l:=length(x);
 50     s:=0;
 51     for i:=1 to l do
 52       s:=(s+(sqr(ord(x[i]))*i mod rd)) mod rd;
 53     p:=hash[s];
 54     while p<>nil do
 55     begin
 56       if p^.st=x then
 57       begin
 58         get:=p^.loc;
 59         break;
 60       end;
 61       p:=p^.next;
 62     end;
 63     if p=nil then
 64     begin
 65       get:=-1;
 66       new(p);
 67       inc(t);
 68       p^.loc:=t;
 69       p^.st:=x;
 70       p^.next:=hash[s];
 71       hash[s]:=p;
 72     end
 73     else if what='+' then
 74     begin
 75       inc(t);
 76       p^.loc:=t;
 77     end;
 78   end;
 79 
 80 procedure rotate(x,w:longint);
 81   var y:longint;
 82   begin
 83     y:=fa[x];
 84     if fa[y]=0 then root:=x
 85     else begin
 86       if son[fa[y],1]=y then son[fa[y],1]:=x
 87       else son[fa[y],2]:=x;
 88     end;
 89     fa[x]:=fa[y];
 90     son[y,3-w]:=son[x,w];
 91     fa[son[x,w]]:=y;
 92     son[x,w]:=y;
 93     fa[y]:=x;
 94     update(y);
 95     update(x);
 96   end;
 97 
 98 procedure up(x:longint);
 99   var y:longint;
100   begin
101     y:=fa[x];
102     while y<>0 do
103     begin
104       if key[y]>key[x] then
105       begin
106         if son[y,1]=x then rotate(x,2)
107         else rotate(x,1);
108       end
109       else break;
110       y:=fa[x];
111     end;
112     if y=0 then root:=x;
113   end;
114 
115 procedure sift(x:longint);
116   var j1,j2:longint;
117   begin
118     repeat
119       j1:=son[x,1];
120       j2:=son[x,2];
121       if (j1=0) and (j2=0) then exit;
122       if j1=0 then rotate(j2,1)
123       else if j2=0 then rotate(j1,2)
124       else begin
125         if (key[j1]>key[j2]) then rotate(j2,1)
126         else rotate(j1,2);
127       end;
128     until false;
129   end;
130 
131 function rank(x:longint):longint;
132   var y,p:longint;
133   begin
134     y:=fa[x];
135     p:=x;
136     rank:=count[son[x,2]];
137     while y<>0 do
138     begin
139       if son[y,1]=p then rank:=rank+count[son[y,2]]+1;
140       p:=y;
141       y:=fa[p];
142     end;
143     rank:=rank+1;
144   end;
145 
146 function kth(x:longint):longint;
147   var p:longint;
148   begin
149     p:=root;
150     while true do
151     begin
152       if count[son[p,2]]+1=x then exit(p);
153       if count[son[p,2]]+1>x then p:=son[p,2]
154       else begin
155         x:=x-count[son[p,2]]-1;
156         p:=son[p,1];
157       end;
158     end;
159   end;
160 
161 procedure insert(s:string;x:longint);
162   var p:longint;
163   begin
164     clear(t);
165     score[t]:=x;
166     key[t]:=trunc(random(ran));
167     na[t]:=s;
168     if root=0 then
169     begin
170       root:=t;
171       fa[t]:=0;
172     end
173     else begin
174       p:=root;
175       repeat
176         inc(count[p]);
177         if x>score[p] then
178         begin
179           if son[p,2]=0 then break;
180           p:=son[p,2];
181         end
182         else begin   //注意后插入的相等分数应放在左子树
183           if son[p,1]=0 then break; 
184           p:=son[p,1];
185         end;
186       until false;
187       if score[p]>=x then son[p,1]:=t else son[p,2]:=t;  
188       fa[t]:=p;
189       up(t);
190     end;
191   end;
192 
193 procedure delete(x:longint);
194   var y:longint;
195   begin
196     sift(x);
197     y:=fa[x];
198     while y<>0 do
199     begin
200       dec(count[y]);
201       y:=fa[y];
202     end;
203     y:=fa[x];
204     if son[y,1]=x then son[y,1]:=0 else son[y,2]:=0;
205     clear(x);
206   end;
207 
208 procedure ask(x:longint);
209   var i,y:longint;
210   begin
211     if x+9>tot then y:=tot else y:=x+9;
212     for i:=x to y do
213     begin
214       write(na[kth(i)]);
215       if i<>y then write(' ');
216     end;
217     writeln;
218   end;
219 
220 begin
221   randomize;
222   readln(n);
223   t:=0;
224   for i:=1 to n do
225   begin
226     read(what);
227     if what='?' then
228     begin
229       readln(s);
230       if (s[1]>='0') and (s[1]<='9') then
231       begin
232         x:=tran(s);
233         ask(x);
234       end
235       else begin
236         x:=get(s);
237         writeln(rank(x));
238       end;
239     end
240     else begin
241       s:='';
242       read(ch);
243       while ch<>' ' do
244       begin
245         s:=s+ch;
246         read(ch);
247       end;
248       x:=0;
249       readln(ss);
250       x:=tran(ss);
251       y:=get(s);
252       if y=-1 then
253       begin
254         inc(tot);
255         insert(s,x);
256       end
257       else begin
258         insert(s,x);
259         delete(y);
260       end;
261     end;
262   end;
263 end.
View Code

 

posted on 2014-07-05 23:06  acphile  阅读(197)  评论(0编辑  收藏  举报