| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
狂顶函数式treap,另附pascal程序In Reply To:把fanhqme惊世骇俗的关于Treap的文章直接转载过来(挖掘Treap的潜力) Posted by:yc5_yc at 2012-12-19 21:48:27 type
arr=record
minm,point,lnext,rnext,adtg,totg,ran,sons:longint;
end;
var
tree:array[0..210000] of arr;
a:array[1..3] of longint;
n,i,m,root:longint;
st:string;
function min(a,b:longint):longint;
begin
if a>b then exit(b) else exit(a);
end;
procedure swap(var a,b:longint);
var
c:longint;
begin
c:=a;
a:=b;
b:=c;
end;
function newpoint(x:longint):longint;
begin
inc(m);
with tree[m] do
begin
minm:=x; point:=x;
lnext:=0; rnext:=0; adtg:=0; totg:=0;
ran:=random(1000000)+1;
sons:=1;
end;
exit(m);
end;
procedure prepare;
begin
randomize;
tree[0].sons:=0;
tree[0].minm:=maxlongint;
m:=0;
root:=newpoint(maxlongint);
end;
procedure pushto(x:longint);
begin
tree[x].totg:=0;
swap(tree[x].lnext,tree[x].rnext);
if tree[x].lnext<>0 then tree[tree[x].lnext].totg:=tree[tree[x].lnext].totg xor 1;
if tree[x].rnext<>0 then tree[tree[x].rnext].totg:=tree[tree[x].rnext].totg xor 1;
end;
procedure pushad(x:longint);
var
t:longint;
begin
t:=tree[x].adtg;
tree[x].adtg:=0;
if tree[x].lnext<>0 then
with tree[tree[x].lnext] do
begin
inc(adtg,t); inc(minm,t); inc(point,t);
end;
if tree[x].rnext<>0 then
with tree[tree[x].rnext] do
begin
inc(adtg,t); inc(minm,t); inc(point,t);
end;
end;
procedure update(x:longint);
begin
tree[x].minm:=min(min(tree[tree[x].lnext].minm,tree[tree[x].rnext].minm),tree[x].point);
tree[x].sons:=tree[tree[x].lnext].sons+tree[tree[x].rnext].sons+1;
end;
procedure push(x:longint);
begin
if tree[x].totg>0 then pushto(x);
if tree[x].adtg<>0 then pushad(x);
end;
procedure split(x,sub:longint;var rs,rb:longint);
var
t:longint;
begin
if x=0 then begin rs:=0; rb:=0; exit; end;
push(x);
if tree[tree[x].lnext].sons>=sub then
begin
rb:=x;
split(tree[x].lnext,sub,rs,t);
tree[x].lnext:=t;
end
else
begin
rs:=x;
split(tree[x].rnext,sub-tree[tree[x].lnext].sons-1,t,rb);
tree[x].rnext:=t;
end;
update(x);
end;
function merge(l,r:longint):longint;
begin
if l=0 then exit(r);
if r=0 then exit(l);
if tree[l].ran<tree[r].ran then
begin
push(r);
tree[r].lnext:=merge(l,tree[r].lnext);
update(r);
merge:=r;
end
else
begin
push(l);
tree[l].rnext:=merge(tree[l].rnext,r);
update(l);
merge:=l;
end;
end;
procedure build;
var
i,x,ts,tb,now:longint;
begin
for i:=1 to n do
begin
readln(x);
now:=newpoint(x);
split(root,i,ts,tb);
root:=merge(merge(ts,now),tb);
end;
end;
procedure trans(st:string;num:longint);
var
i,j,k:longint;
begin
st:=st+' ';
j:=1;
while st[j]<>' ' do inc(j);
while st[j]=' ' do inc(j);
for i:=1 to num do
begin
k:=j;
while st[j]<>' ' do inc(j);
val(copy(st,k,j-k),a[i]);
inc(j);
end;
end;
procedure add(left,right,sub:longint);
var
t1,t2,t3,t4:longint;
begin
split(root,left,t1,t2);
split(t2,right-left+1,t3,t4);
inc(tree[t3].adtg,sub);
inc(tree[t3].point,sub);
inc(tree[t3].minm,sub);
root:=merge(t1,merge(t3,t4));
end;
procedure reverse(left,right:longint);
var
t1,t2,t3,t4:longint;
begin
split(root,left,t1,t2);
split(t2,right-left+1,t3,t4);
tree[t3].totg:=tree[t3].totg xor 1;
root:=merge(t1,merge(t3,t4));
end;
procedure revolve(left,right,sub:longint);
var
t1,t2,t3,t4,t5,t6:longint;
begin
if sub<0 then sub:=((-sub) div (right-left+1)+1)*(right-left+1)+sub;
sub:=sub mod (right-left+1);
if sub=0 then exit;
split(root,left,t1,t2);
split(t2,right-left+1,t3,t4);
split(t3,right-left+1-sub,t5,t6);
root:=merge(t1,merge(merge(t6,t5),t4));
end;
procedure insert(left,sub:longint);
var
t1,t2,now:longint;
begin
now:=newpoint(sub);
split(root,left+1,t1,t2);
root:=merge(t1,merge(now,t2));
end;
procedure delete(left:longint);
var
t1,t2,t3,t4:longint;
begin
split(root,left,t1,t2);
split(t2,1,t3,t4);
root:=merge(t1,t4);
end;
procedure getmin(left,right:longint);
var
t1,t2,t3,t4:longint;
begin
split(root,left,t1,t2);
split(t2,right-left+1,t3,t4);
writeln(tree[t3].minm);
root:=merge(t1,merge(t3,t4));
end;
begin
readln(n);
prepare;
build;
readln(n);
for i:=1 to n do
begin
readln(st);
case st[1] of
'A':begin trans(st,3); add(a[1],a[2],a[3]); end;
'R':begin
if st[4]='E' then begin trans(st,2); reverse(a[1],a[2]); end
else begin trans(st,3); revolve(a[1],a[2],a[3]); end;
end;
'I':begin trans(st,2); insert(a[1],a[2]); end;
'D':begin trans(st,1); delete(a[1]); end;
'M':begin trans(st,2); getmin(a[1],a[2]); end;
end;
end;
end.
Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator