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