为防止广告,目前nocow只有登录用户能够创建新页面。如要创建页面请先登录/注册(新用户需要等待1个小时才能正常使用该功能)。

Code:Treap/Pascal

来自NOCOW
(跳转自Treap Pascal)
跳转到: 导航, 搜索
插入非格式文本
(*
	Problem: Treap
	Author: LiuQin
	Method: DS
	Data Strucktrue: Treap
	Date: 2006-12-11
	Status: Done
	Remarks: 标准Treap
*)
const
	Infinity = MaxLongint div 2;
type
	TIndex = Longint;
	TData = Int64;
	PTreapNode = ^TTreapNode;
	TTreapNode = record
		Key: TData;
		Priority: TIndex;
		Count: TIndex;
		Total: TIndex;
		LeftNode, RightNode: PTreapNode;
	end;
	TTreap = object
		NullNode, RootNode: PTreapNode;
		procedure Initialize;
		procedure UpdateSum(var CurNode: PTreapNode);
		procedure LeftRotate(var CurNode: PTreapNode);
		procedure RightRotate(var CurNode: PTreapNode);
		procedure InsertNode(var CurNode: PTreapNode; const Key: TData);
		procedure DeleteNode(var CurNode: PTreapNode; const Key: TData);
		function GetMinimum: TData;
		function GetMaximum: TData;
		procedure Insert(const Key: TData);
		procedure Delete(const Key: TData);
		function FindRank(Rank: TIndex): TData;
		function GetRank(const Key: TData): TIndex;
	end;
 
procedure TTreap.Initialize;
begin
	New(NullNode);
	NullNode^.Priority := Infinity;
	NullNode^.Count := 0;
	NullNode^.Total := 0;
	NullNode^.LeftNode := NullNode;
	NullNode^.RightNode := NullNode;
	RootNode := NullNode;
end;
procedure TTreap.UpdateSum(var CurNode: PTreapNode);
begin
	CurNode^.Total := CurNode^.LeftNode^.Total + CurNode^.RightNode^.Total + CurNode^.Count;
end;
procedure TTreap.LeftRotate(var CurNode: PTreapNode);
var
	TmpNode: PTreapNode;
begin
	TmpNode := CurNode^.LeftNode;
	CurNode^.LeftNode := TmpNode^.RightNode;
	TmpNode^.RightNode := CurNode;
	UpdateSum(CurNode);
	UpdateSum(TmpNode);
	CurNode := TmpNode;
end;
procedure TTreap.RightRotate(var CurNode: PTreapNode);
var
	TmpNode: PTreapNode;
begin
	TmpNode := CurNode^.RightNode;
	CurNode^.RightNode := TmpNode^.LeftNode;
	TmpNode^.LeftNode := CurNode;
	UpdateSum(CurNode);
	UpdateSum(TmpNode);
	CurNode := TmpNode;
end;
procedure TTreap.InsertNode(var CurNode: PTreapNode; const Key: TData);
begin
	if CurNode = NullNode then
	begin
		New(CurNode);
		CurNode^.Key := Key;
		CurNode^.Priority := Random(Infinity);
		CurNode^.Count := 1;
		CurNode^.Total := 1;
		CurNode^.LeftNode := NullNode;
		CurNode^.RightNode := NullNode;
	end
	else if Key < CurNode^.Key then
	begin
		InsertNode(CurNode^.LeftNode, Key);
		if CurNode^.LeftNode^.Priority < CurNode^.Priority then
			LeftRotate(CurNode);
	end
	else if Key > CurNode^.Key then
	begin
		InsertNode(CurNode^.RightNode, Key);
		if CurNode^.RightNode^.Priority < CurNode^.Priority then
			RightRotate(CurNode);
	end
	else //if CurNode^.Key = Key then
		Inc(CurNode^.Count);
	UpdateSum(CurNode);
end;
procedure TTreap.DeleteNode(var CurNode: PTreapNode; const Key: TData);
begin
	if CurNode <> NullNode then
		if Key < CurNode^.Key then
			DeleteNode(CurNode^.LeftNode, Key)
		else if Key > CurNode^.Key then
			DeleteNode(CurNode^.RightNode, Key)
		else if CurNode^.Count > 1 then
			Dec(CurNode^.Count)
		else if (CurNode^.LeftNode = NullNode) and (CurNode^.RightNode = NullNode) then
		begin
			Dispose(CurNode);
			CurNode := NullNode;
		end
		else
		begin
			if CurNode^.LeftNode^.Priority < CurNode^.RightNode^.Priority then
				LeftRotate(CurNode)
			else
				RightRotate(CurNode);
			DeleteNode(CurNode, Key);
		end;
	UpdateSum(CurNode);
end;
function TTreap.GetMinimum: TData;
var
	CurNode: PTreapNode;
begin
	CurNode := RootNode;
	while CurNode^.LeftNode <> NullNode do
		CurNode := CurNode^.LeftNode;
	Result := CurNode^.Key;
end;
function TTreap.GetMaximum: TData;
var
	CurNode: PTreapNode;
begin
	CurNode := RootNode;
	while CurNode^.RightNode <> NullNode do
		CurNode := CurNode^.RightNode;
	Result := CurNode^.Key;
end;
procedure TTreap.Insert(const Key: TData);
begin
	InsertNode(RootNode, Key);
end;
procedure TTreap.Delete(const Key: TData);
begin
	DeleteNode(RootNode, Key);
end;
function TTreap.FindRank(Rank: TIndex): TData;
var
	CurNode: PTreapNode;
begin
	CurNode := RootNode;
	while CurNode <> NullNode do
		if Rank <= CurNode^.LeftNode^.Total then
			CurNode := CurNode^.LeftNode
		else
		begin
			Dec(Rank, CurNode^.LeftNode^.Total);
			if Rank <= CurNode^.Count then Break;
			Dec(Rank, CurNode^.Count);
			CurNode := CurNode^.RightNode;
		end;
	Result := CurNode^.Key;
end;
function TTreap.GetRank(const Key: TData): TIndex;
var
	CurNode: PTreapNode;
begin
	CurNode := RootNode;
	Result := 0;
	while CurNode <> NullNode do
		if Key < CurNode^.Key then
			CurNode := CurNode^.LeftNode
		else
		begin
			Inc(Result, CurNode^.LeftNode^.Total + CurNode^.Count);
			if Key = CurNode^.Key then Break;
			CurNode := CurNode^.RightNode;
		end;
end;
var
	M: TIndex;
	Treap: TTreap;
procedure Main;
var
	x: TIndex;
	Ch, Tmp: Char;
begin
	Treap.Initialize;
	ReadLn(M);
	while M > 0 do
	begin
		Dec(M);
		Read(Ch, Tmp);
		while Tmp <> ' ' do
			Read(Tmp);
		Readln(x);
		if Ch = 'I' Then
			Treap.InsertNode(Treap.RootNode, x)
		else if Ch = 'D' Then
				Treap.DeleteNode(Treap.RootNode, x)
		else if Ch = 'F' Then
				Writeln(Treap.FindRank(x))
		else if Ch = 'G' Then
				Writeln(Treap.GetRank(x));
	end;
end;
begin
	Assign(Input, 'bst.in');
	Reset(Input);
	Assign(Output, 'bst.out');
	Rewrite(Output);
	Main;
	Close(Input);
	Close(Output);
end.


//不用指针,静态的Treap代码 By Jollwish
type node=record
      f,lc,rc,key:longint;
      fix:extended;
     end;
 
var a:array[1..100000]of node;
    n,m,root:longint;
 
function search(x,k:longint):longint;
 begin
  if k=0 then exit(0);
  if a[k].key=x then exit(k);
  if a[k].key>x then exit(search(x,a[k].lc));
  if a[k].key<x then exit(search(x,a[k].rc));
 end;
 
procedure rotate_left(var k:longint);
 var y:longint;
 begin
  y:=a[k].rc;
  a[k].rc:=a[y].lc;
  if a[y].lc>0 then a[a[y].lc].f:=k;
  a[y].f:=a[k].f;
  if a[k].f=0
   then root:=y
   else if k=a[a[k].f].lc
    then y:=a[a[k].f].lc
    else y:=a[a[k].f].rc;
  k:=a[y].lc;
  a[k].f:=y;
 end;
 
procedure rotate_right(var k:longint);
 var y:longint;
 begin
  y:=a[k].lc;
  a[k].lc:=a[y].rc;
  if a[y].rc>0 then a[a[y].rc].f:=k;
  a[y].f:=a[k].f;
  if a[k].f=0
   then root:=y
   else if k=a[a[k].f].lc
    then y:=a[a[k].f].lc
    else y:=a[a[k].f].rc;
  k:=a[y].rc;
  a[k].f:=y;
 end;
 
procedure insert(x,k:longint);
 var tmp:longint;
 begin
  if a[k].key>x then
   begin
    if a[k].lc=0 then
     begin
      inc(n);
      a[n].f:=k;
      a[n].key:=x;
      randomize;
      a[n].fix:=random;
      a[k].lc:=n;
	  tmp:=a[n].f;
      if a[n].fix<a[tmp].fix then rotate_right(tmp);
	  a[n].f:=tmp;
     end
    else insert(x,a[k].lc);
   end;
  if a[k].key<x then
   begin
    if a[k].rc=0 then
     begin
      inc(n);
      a[n].f:=k;
      a[n].key:=x;
      randomize;
      a[n].fix:=random;
      a[k].rc:=n;
	  tmp:=a[n].f;
      if a[n].fix<a[tmp].fix then rotate_left(tmp);
	  a[n].f:=tmp;
     end
    else insert(x,a[k].rc);
  end;
 end;
 
procedure remove(k:longint);
 begin
  while (a[k].lc>0)or(a[k].rc>0) do
   begin
    if a[k].lc=0 then
     begin 
      rotate_left(k);
      continue;
     end;
   if a[k].rc=0 then
    begin
     rotate_right(k);
     continue;
    end;
   if a[a[k].lc].fix>a[a[k].rc].fix
    then rotate_left(k)
    else rotate_right(k);
  end;
  if a[a[k].f].lc=k
   then a[a[k].f].lc:=0
   else a[a[k].f].rc:=0;
 end;
 
procedure init;
 var i,x,o:longint;
 begin
  fillchar(a,sizeof(a),0);
  readln(o,m);
  read(x);
  a[1].key:=x;
  n:=1;
  root:=1;
  for i:=2 to o do
   begin
    read(x);
    insert(x,root);
   end;
  readln;
 end;
 
procedure main;
 var i,p,q:longint;
     ch,space:char;
 begin
  for i:=1 to m do
   begin
    read(ch);
    read(space);
    readln(p);
    case ch of
     'I':insert(p,root);
     'S':begin
          q:=search(p,root);
          if q=0 then writeln('NO') else writeln('YES');
         end;
     'D':begin
          q:=search(p,root);
          remove(q);
         end; 
    end;
   end;
 end;
 
begin
 init;
 main;
end.
//By Jiguanglizipao
Program treap; //数组模拟链表,带内存回收,支持插入、查找、删除
Type
  Rec1 = Record
    f, w, p: Longint; //父节点:f 值:w 随机值:p
    a : Array[0..1] Of Longint;//左儿子:0, 右儿子:1
  End;
Const
  infile = 'treap.in';
  outfile = 'treap.out';
  maxn = 1000000;
Var
  tree : Array[0..maxn] Of Rec1; //树
  d : Array[1..maxn] Of Longint; //回收内存循环队列
  n, i, h, t, x, tn : Longint;
  ch : char;
Procedure rotate(k, p : Longint); //旋转 左0右1
Begin
  If tree[tree[k].f].a[0] = k Then tree[tree[k].f].a[0] := tree[k].a[1-p] Else tree[tree[k].f].a[1] := tree[k].a[1-p];
  tree[tree[k].a[1-p]].f := tree[k].f;
  tree[k].f := tree[k].a[1-p];
  tree[k].a[1-p] := tree[tree[k].f].a[p];
  tree[tree[k].a[1-p]].f := k;
  tree[tree[k].f].a[p] := k;
End;
Procedure up(k : Longint); //维护堆的性质
Begin
  If (tree[k].f = 0) Or (tree[k].p <= tree[tree[k].f].p) Then Exit;
  If tree[tree[k].f].a[1] = k Then rotate(tree[k].f, 0) Else rotate(tree[k].f, 1);
  up(k);
End;
Procedure Insert(x, k : Longint); //在K的儿子中插入一个值为x的点
Var
  p, o : Longint;
Begin
  If tree[k].w = x Then Exit; //如果已存在,退出
  If tree[k].w > x Then o := 0 Else o := 1;
  If tree[k].a[o] <> 0 Then Insert(x, tree[k].a[o]) Else Begin //如果K的儿子不能插入,找他的儿子
    If h = t Then Begin
      Inc(tn);
      p := tn;
    End Else Begin
      h := h mod maxn + 1;
      p := d[h];
    End;
    tree[k].a[o] := p;
    tree[p].w := x;
    tree[p].f := k;
    tree[p].p := random(maxn);
    up(p); //维护堆
  End;
End;
Function Find(x, k : Longint) : Longint; //查找X
Begin
  If ((x < tree[k].w) And (tree[k].a[0] = 0)) Or ((tree[k].w < x) And (tree[k].a[1] = 0)) Then Exit(0);
  If x = tree[k].w Then Exit(k);
  If x < tree[k].w Then find := find(x, tree[k].a[0]) Else find := find(x, tree[k].a[1]);
End;
Procedure Delete(x : Longint); //删除X
Var
  k : Longint;
Begin
  k := find(x, tree[0].a[1]); //查找X是否存在
  If k = 0 Then Exit;
  While (tree[k].a[0] <> 0) Or (tree[k].a[1] <> 0)Do Begin //将这个点旋转至最底层
    If tree[k].a[0] <> 0 Then rotate(k, 1) Else rotate(k, 0);
  End;
  t := t Mod maxn + 1; //删除
  If x < tree[tree[k].f].w Then tree[tree[k].f].a[0] := 0 Else tree[tree[k].f].a[1] := 0;
  d[t] := k;
End;
Begin
  Randomize;
  Assign(input, infile);
  Assign(output, outfile);
  Reset(input);
  Rewrite(output);
  ReadLn(n);
  tree[0].w := -maxlongint;
  For i:=1 To n Do Begin
    ReadLn(ch, x);
    If ch = 'I' Then Insert(x, tree[0].a[1]);
    If ch = 'D' Then Delete(x);
    If ch = 'F' Then If Find(x, tree[0].a[1]) = 0 Then WriteLn('NO') Else WriteLn('YES');
  End;
  Close(input);
  Close(output);
End.

</source>

//Author: 奇の犽
// Problem: HNOI 2004 day1 pet 宠物收养所
type ch=record
          l,r,key:longint;
          fix:real;
        end;
var i,x,b,c,y,root,tot,ans,n,kind:longint;
    a:array[0..80001] of ch;
 
procedure right(var x:longint);
var k:longint;
begin
  k:=a[x].l;
  a[x].l:=a[k].r;
  a[k].r:=x;
  x:=k;
end;
 
procedure left(var x:longint);
var k:longint;
begin
  k:=a[x].r;
  a[x].r:=a[k].l;
  a[k].l:=x;
  x:=k;
end;
 
procedure insert(var x:longint;y:longint);
begin
  if x=0 then
    begin
      x:=tot;
      a[x].key:=y;
      a[x].fix:=random;
      exit;
    end;
  if y<a[x].key then
    begin
      insert(a[x].l,y);
      if a[a[x].l].fix<a[x].fix then right(x);
    end
    else begin
      insert(a[x].r,y);
      if a[a[x].r].fix<a[x].fix then left(x);
    end;
end;
 
procedure find(x,y:longint);
begin
  if x=0 then exit;
  if (abs(a[x].key-y)<b)or((abs(a[x].key-y)=b)and(a[x].key<c)) then
    begin
      b:=abs(a[x].key-y);
      c:=a[x].key;
    end;
  if a[x].key<y then find(a[x].r,y)
    else find(a[x].l,y);
end;
 
procedure delete(var x:longint;y:longint);
begin
  if x=0 then exit;
  if a[x].key<y then delete(a[x].r,y);
  if a[x].key>y then delete(a[x].l,y);
  if a[x].key=y then
    if a[x].l*a[x].r=0 then x:=a[x].l+a[x].r
      else if a[a[x].l].fix<a[x].fix then
        begin
          right(x);
          delete(a[x].r,y);
        end
        else begin
          left(x);
          delete(a[x].l,y);
        end;
end;
 
begin
  assign(input,'pet.in');reset(input);
  assign(output,'pet.out');rewrite(output);
  readln(n);kind:=-1;root:=0;
  ans:=0;tot:=0;randomize;
  fillchar(a,sizeof(a),0);
  for i:=1 to n do
    begin
      readln(x,y);
      case x of
        0:begin
            if kind=-1 then
              begin
                inc(tot);
                insert(root,y);
                kind:=0;
                continue;
              end;
            if kind=0 then
              begin
                inc(tot);
                insert(root,y);
                continue;
              end;
            b:=maxlongint;
            find(root,y);
            ans:=(ans+abs(y-c)) mod 1000000;
            delete(root,c);
            dec(tot);
            if tot=0 then
              begin
                kind:=-1;
                fillchar(a,sizeof(a),0);
                root:=0;
              end;
          end;
        1:begin
            if kind=-1 then
              begin
                inc(tot);
                insert(root,y);
                kind:=1;
                continue;
              end;
            if kind=1 then
              begin
                inc(tot);
                insert(root,y);
                continue;
              end;
            b:=maxlongint;
            find(root,y);
            ans:=(ans+abs(y-c)) mod 1000000;
            delete(root,c);
            dec(tot);
            if tot=0 then
              begin
                kind:=-1;
                fillchar(a,sizeof(a),0);
                root:=0;
              end;
          end;
      end;
    end;
  writeln(ans);
  close(input);close(output);
end.
个人工具