平衡树模板在此!
写了treap(话说好久没写splay了)
注意对相同元素的处理
UPD:其实这里处理的不好,每个点可以代表一个元素值,然后记录出现次数即可,不用新添一个点
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 const rd=200007; 2 var fa,key,a,count:array[0..200010] of longint; 3 son:array[0..200010,1..2] of longint; 4 t,root,ch,x,i,n:longint; 5 6 procedure clear(x:longint); 7 begin 8 son[x,1]:=0; 9 son[x,2]:=0; 10 fa[x]:=0; 11 count[x]:=1; 12 fa[0]:=-1; 13 count[0]:=0; 14 end; 15 16 procedure update(x:longint); 17 begin 18 count[x]:=count[son[x,1]]+count[son[x,2]]+1; 19 end; 20 21 procedure rotate(x,w:longint); 22 var y:longint; 23 begin 24 y:=fa[x]; 25 if fa[y]<>0 then 26 begin 27 if son[fa[y],1]=y then son[fa[y],1]:=x 28 else son[fa[y],2]:=x; 29 end 30 else root:=x; 31 fa[x]:=fa[y]; 32 son[y,3-w]:=son[x,w]; 33 fa[son[x,w]]:=y; 34 son[x,w]:=y; 35 fa[y]:=x; 36 update(y); 37 update(x); 38 end; 39 40 procedure up(i:longint); 41 var j:longint; 42 begin 43 j:=fa[i]; 44 while (j<>0) and (key[j]>key[i]) do 45 begin 46 if son[j,1]=i then rotate(i,2) 47 else rotate(i,1); 48 j:=fa[i]; 49 end; 50 end; 51 52 procedure sift(i:longint); 53 var j1,j2:longint; 54 begin 55 repeat 56 j1:=son[i,1]; 57 j2:=son[i,2]; 58 if (j1=0) and (j2=0) then break; 59 if (j1=0) then 60 rotate(j2,1) 61 else if j2=0 then 62 rotate(j1,2) 63 else begin 64 if (key[j1]>key[j2]) then 65 rotate(j2,1) 66 else rotate(j1,2); 67 end; 68 until false; 69 end; 70 71 function find(x:longint):longint; 72 var p:longint; 73 begin 74 p:=root; 75 while true do 76 begin 77 if a[p]=x then exit(p); 78 if a[p]>x then p:=son[p,1] 79 else p:=son[p,2]; 80 end; 81 end; 82 83 procedure insert(x:longint); 84 var p:longint; 85 begin 86 inc(t); 87 key[t]:=trunc(random*rd)+1; 88 a[t]:=x; 89 clear(t); 90 if root=0 then root:=t 91 else begin 92 p:=root; 93 repeat 94 inc(count[p]); 95 if a[p]>x then 96 begin 97 if son[p,1]=0 then break; 98 p:=son[p,1]; 99 end 100 else begin 101 if son[p,2]=0 then break; 102 p:=son[p,2]; 103 end; 104 until false; 105 fa[t]:=p; 106 if a[p]>x then son[p,1]:=t else son[p,2]:=t; 107 up(t); 108 end; 109 end; 110 111 procedure delete(x:longint); 112 var i,p:longint; 113 begin 114 i:=find(x); 115 sift(i); 116 if fa[i]=0 then root:=0; 117 p:=fa[i]; 118 while p<>0 do 119 begin 120 dec(count[p]); 121 p:=fa[p]; 122 end; 123 if son[fa[i],1]=i then son[fa[i],1]:=0 124 else son[fa[i],2]:=0; 125 clear(i); 126 end; 127 128 function kth(x:longint):longint; 129 var p:longint; 130 begin 131 p:=root; 132 while true do 133 begin 134 if count[son[p,1]]+1=x then exit(a[p]); 135 if count[son[p,1]]+1>x then p:=son[p,1] 136 else begin 137 x:=x-count[son[p,1]]-1; 138 p:=son[p,2]; 139 end; 140 end; 141 end; 142 143 function rank(x:longint):longint; 144 var p:longint; 145 begin 146 p:=root; 147 rank:=1; 148 while p<>0 do 149 begin 150 if a[p]>=x then p:=son[p,1] //注意这里的等号,因为是要找最小的排名 151 else begin 152 rank:=rank+count[son[p,1]]+1; 153 p:=son[p,2]; 154 end; 155 end; 156 end; 157 158 function pre(p,x:longint):longint; 159 begin 160 if p=0 then exit(-1); 161 if a[p]>=x then exit(pre(son[p,1],x)) 162 else begin 163 pre:=pre(son[p,2],x); 164 if pre=-1 then pre:=a[p]; 165 end; 166 end; 167 168 function succ(p,x:longint):longint; 169 begin 170 if p=0 then exit(-1); 171 if a[p]<=x then exit(succ(son[p,2],x)) 172 else begin 173 succ:=succ(son[p,1],x); 174 if succ=-1 then succ:=a[p]; 175 end; 176 end; 177 178 begin 179 randomize; 180 readln(n); 181 for i:=1 to n do 182 begin 183 readln(ch,x); 184 if ch=1 then 185 insert(x) 186 else if ch=2 then 187 delete(x) 188 else if ch=3 then 189 writeln(rank(x)) 190 else if ch=4 then 191 writeln(kth(x)) 192 else if ch=5 then 193 writeln(pre(root,x)) 194 else writeln(succ(root,x)); 195 end; 196 end.