花了一上午大概复习了一下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.