算法模板——平衡树Treap 2

实现功能:同平衡树Treap 1(BZOJ3224 / tyvj1728)

这次的模板有了不少的改进,显然更加美观了,几乎每个部分都有了不少简化,尤其是删除部分,这个参照了hzwer神犇的写法,在此鸣谢,然后,贴模板走人

  1 var
  2    i,j,k,l,m,n,head,tot:longint;
  3    a,b,lef,rig,fix:array[0..100010] of longint;
  4 function min(x,y:longint):longint;
  5          begin
  6               if x<y then min:=x else min:=y;
  7          end;
  8 function max(x,y:longint):longint;
  9          begin
 10               if x>y then max:=x else max:=y;
 11          end;
 12 procedure lt(var x:longint);
 13           var f,r:longint;
 14           begin
 15                if (x=0) or (rig[x]=0) then exit;
 16                b[rig[x]]:=b[x];b[x]:=b[lef[x]]+b[lef[rig[x]]]+1;
 17                f:=x;r:=rig[x];
 18                rig[f]:=lef[r];
 19                lef[r]:=f;
 20                x:=r;
 21           end;
 22 procedure rt(var x:longint);
 23           var f,l:longint;
 24           begin
 25                if (x=0) or (lef[x]=0) then exit;
 26                b[lef[x]]:=b[x];b[x]:=b[rig[x]]+b[rig[lef[x]]]+1;
 27                f:=x;l:=lef[x];
 28                lef[f]:=rig[l];
 29                rig[l]:=f;
 30                x:=l;
 31           end;
 32 function newp(x:longint):longint;
 33          begin
 34               inc(tot);newp:=tot;
 35               a[tot]:=x;b[tot]:=1;
 36               lef[tot]:=0;rig[tot]:=0;
 37               fix[tot]:=random(maxlongint);
 38          end;
 39 procedure ins(var x:longint;y:longint);
 40           begin
 41                if x=0 then
 42                   begin
 43                        x:=newp(y);
 44                        exit;
 45                   end;
 46                if y<a[x] then
 47                   begin
 48                        ins(lef[x],y);b[x]:=b[lef[x]]+b[rig[x]]+1;
 49                        if fix[lef[x]]<fix[x] then rt(x);
 50                   end
 51                else
 52                    begin
 53                         ins(rig[x],y);b[x]:=b[lef[x]]+b[rig[x]]+1;
 54                         if fix[rig[x]]<fix[x] then lt(x);
 55                    end;
 56           end;
 57 procedure del(var x:longint;y:longint);
 58           begin
 59                if x=0 then exit;
 60                if a[x]=y then
 61                   begin
 62                        if lef[x]=0 then x:=rig[x] else
 63                        if rig[x]=0 then x:=lef[x] else
 64                        if fix[lef[x]]>fix[rig[x]] then
 65                           begin
 66                                lt(x);del(lef[x],y);
 67                                b[x]:=b[lef[x]]+b[rig[x]]+1;
 68                           end
 69                        else
 70                            begin
 71                                 rt(x);del(rig[x],y);
 72                                 b[x]:=b[lef[x]]+b[rig[x]]+1;
 73                            end;
 74                   end
 75                else if y<a[x] then
 76                     begin
 77                          del(lef[x],y);
 78                          b[x]:=b[lef[x]]+b[rig[x]]+1;
 79                     end
 80                else begin
 81                          del(rig[x],y);
 82                          b[x]:=b[lef[x]]+b[rig[x]]+1;
 83                     end;
 84           end;
 85 function getrank(x,y:longint):longint;
 86          begin
 87               if x=0 then exit(0);
 88               if y>a[x] then exit(b[lef[x]]+1+getrank(rig[x],y)) else exit(getrank(lef[x],y));
 89          end;
 90 function rankget(x,y:longint):longint;
 91          begin
 92               if y=(b[lef[x]]+1) then exit(a[x]);
 93               if y<(b[lef[x]]+1) then exit(rankget(lef[x],y)) else exit(rankget(rig[x],y-1-b[lef[x]]));
 94          end;
 95 function getpre(x,y:longint):longint;
 96          begin
 97               if x=0 then exit(-maxlongint);
 98               if a[x]<y then exit(max(a[x],getpre(rig[x],y))) else exit(getpre(lef[x],y));
 99          end;
100 function getsuc(x,y:longint):longint;
101          begin
102               if x=0 then exit(maxlongint);
103               if a[x]>y then exit(min(a[x],getsuc(lef[x],y))) else exit(getsuc(rig[x],y));
104          end;
105 begin
106      readln(n);tot:=0;head:=0;
107      for i:=1 to n do
108          begin
109               readln(j,k);
110               case j of
111                    1:ins(head,k);
112                    2:del(head,k);
113                    3:writeln(getrank(head,k)+1);
114                    4:writeln(rankget(head,k));
115                    5:writeln(getpre(head,k));
116                    6:writeln(getsuc(head,k));
117               end;
118          end;
119 end.
时间: 2024-10-23 13:59:44

算法模板——平衡树Treap 2的相关文章

算法模板——平衡树Treap

实现功能如下——1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小于x,且最大的数)6. 求x的后继(后继定义为大于x,且最小的数) 本程序的实现原理为Treap平衡树 详见BZOJ3224 1 var 2 i,j,k,l,m,n,head,ts:longint;f1:text; 3 a,b,fix,lef,rig:array[0..500000] of longint; 4

luoguP3369[模板]普通平衡树(Treap/SBT) 题解

链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<algorithm> #include<ctime> #include<queue> #incl

tarjan算法模板

var {left表示点 root 没离开栈 vis表示点 root 有没有被访问过} i,n,m,now,time,color,top:longint; v:array[0..10001] of record start:longint;end; e:array[0..100001] of record y,next:longint;end; dfn,low,stack,encolor:array[0..10001] of longint; vis,left:array[0..10001] o

prim算法模板

var g:array[1..10,1..10] of longint; d:array[1..10] of longint; f:array[1..10] of boolean; procedure prim; var i,j,k,min:longint; begin fillchar(g,sizeof(g),0); fillchar(f,sizeof(f),0); for i:=1 to n do d[i]:=g[1,i]; f[1]:=true; for i:=2 to n do begi

bellman-ford算法模板

有SPFA模板,bellman-ford模板显然是多余的. var e:array[1..maxe]of record a,b,w:longint;end; { 距源点s距离 } dis:array[1..maxn]of longint; { 前驱 } pre:array[1..maxn]of longint; m,n,s:longint; procedure relax(u,v,w:longint); begin if dis[u]+w<dis[v] then begin dis[v]:=di

Floyd判最小环算法模板

算法思想:如果存在最小环,会在编号最大的点u更新最短路径前找到这个环,发现的方法是,更新最短路径前,遍历i,j点对,一定会发现某对i到j的最短路径长度dis[i][j]+mp[j][u]+mp[u][i] != INF,这时i,j是图中挨着u的两个点,因为在之前最短路更新过程中,u没有参与更新,所以dis[i][j]所表示的路径中不会出现u,如果成立,则一定是一个环.用Floyd算法来实现.但是对于负环此算法失效,因为有负环时,dis[i][j]已经不能保证i到j的路径上不会经过同一个点多次了.

hdu 1711 KMP算法模板题

题意:给你两个串,问你第二个串是从第一个串的什么位置開始全然匹配的? kmp裸题,复杂度O(n+m). 当一个字符串以0为起始下标时.next[i]能够描写叙述为"不为自身的最大首尾反复子串长度". 当发生失配的情况下,j的新值next[j]取决于模式串中T[0 ~ j-1]中前缀和后缀相等部分的长度, 而且next[j]恰好等于这个最大长度. 防止超时.注意一些细节.. 另外:尽量少用strlen.变量记录下来使用比較好,用字符数组而不用string //KMP算法模板题 //hdu

HDU 2544 最短路(我的dijkstra算法模板、SPAFA算法模板)

思路:这道题是基础的最短路径算法,可以拿来试一下自己对3种方法的理解 dijkstra主要是从第一个点开始枚举,每次枚举出当当前最小的路径,然后再以那最小的路径点为起点,求出它到其它未标记点的最短距离 bellman-ford 算法则是假设有向网中有n 个顶点.且不存在负权值回路,从顶点v1 和到顶点v2 如果存在最短路径,则此路径最多有n-1 条边.这是因为如果路径上的边数超过了n-1 条时,必然会重复经过一个顶点,形成回路:而如果这个回路的权值总和为非负时,完全可以去掉这个回路,使得v1到v

kruskal 算法模板

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2896 #include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int u,v,w; }q[200001]; int bin[50001]; int n,m,ans; int cmp(const void *a,const void