bzoj 3196二逼平衡树 线段树套平衡树
比较裸的树套树,对于区间K值bz上有一道裸题,详见题解http://www.cnblogs.com/BLADEVIL/p/3455336.html(其实题解也不是很详细)
//By BLADEVIL type rec =record left, right, root :longint; end; var n, m :longint; a :array[0..100100] of longint; t :array[0..300300] of rec; b_left, b_right, b_key :array[0..1000010] of longint; b_size :array[0..1000010] of longint; tot :longint; function min(a,b:longint):longint; begin if a>b then min:=b else min:=a; end; function max(a,b:longint):longint; begin if a>b then max:=a else max:=b; end; procedure left_rotate(var t:longint); var k :longint; begin k:=b_right[t]; b_right[t]:=b_left[k]; b_left[k]:=t; b_size[k]:=b_size[t]; b_size[t]:=b_size[b_left[t]]+b_size[b_right[t]]+1; t:=k; end; procedure right_rotate(var t:longint); var k :longint; begin k:=b_left[t]; b_left[t]:=b_right[k]; b_right[k]:=t; b_size[k]:=b_size[t]; b_size[t]:=b_size[b_left[t]]+b_size[b_right[t]]+1; t:=k; end; procedure maintain(var t:longint;flag:boolean); begin if not flag then begin if b_size[b_left[b_left[t]]]>b_size[b_right[t]] then right_rotate(t) else if b_size[b_right[b_left[t]]]>b_size[b_right[t]] then begin left_rotate(b_left[t]); right_rotate(t); end else exit; end else begin if b_size[b_right[b_right[t]]]>b_size[b_left[t]] then left_rotate(t) else if b_size[b_left[b_right[t]]]>b_size[b_left[t]] then begin right_rotate(b_right[t]); left_rotate(t); end else exit; end; maintain(b_left[t],false); maintain(b_right[t],true); maintain(t,true); maintain(t,false); end; procedure insert(var t:longint;v:longint); begin if t=0 then begin inc(tot); t:=tot; b_left[t]:=0; b_right[t]:=0; b_size[t]:=1; b_key[t]:=v; end else begin inc(b_size[t]); if v>=b_key[t] then insert(b_right[t],v) else insert(b_left[t],v); maintain(t,v>=b_key[t]); end; end; function delete(var t:longint; v:longint):longint; begin dec(b_size[t]); if (b_key[t]=v) or (b_key[t]<v) and (b_right[t]=0) or (b_key[t]>v) and (b_left[t]=0) then begin delete:=b_key[t]; if (b_left[t]=0) or (b_right[t]=0) then t:=b_left[t]+b_right[t] else b_key[t]:=delete(b_left[t],v+1); end else if v>b_key[t] then delete:=delete(b_right[t],v) else delete:=delete(b_left[t],v); end; procedure build(x,l,r:longint); var mid :longint; i :longint; begin t[x].left:=l; t[x].right:=r; t[x].root:=0; for i:=l to r do insert(t[x].root,a[i]); if l=r then exit; with t[x] do mid:=(left+right) div 2; build(x*2,l,mid); build(x*2+1,mid+1,r); end; function b_rank(var t:longint;v:longint):longint; begin if t=0 then exit(0); if v<=b_key[t] then b_rank:=b_rank(b_left[t],v) else b_rank:=b_rank(b_right[t],v)+b_size[b_left[t]]+1; end; procedure init; var i :longint; begin read(n,m); for i:=1 to n do read(a[i]); build(1,1,n); end; function rank(x,l,r,y:longint):longint; var mid :longint; begin if (t[x].left=l) and (t[x].right=r) then begin rank:=b_rank(t[x].root,y); exit; end; with t[x] do mid:=(left+right) div 2; if mid<l then rank:=rank(x*2+1,l,r,y) else if mid>=r then rank:=rank(x*2,l,r,y) else rank:=rank(x*2,l,mid,y)+rank(x*2+1,mid+1,r,y); end; procedure askrank(l,r,x:longint); begin writeln(rank(1,l,r,x)+1); end; procedure change(x,y,z,c:longint); var mid :longint; begin mid:=delete(t[x].root,c); insert(t[x].root,z); if t[x].left=t[x].right then exit; with t[x] do mid:=(left+right) div 2; if y>mid then change(x*2+1,y,z,c) else change(x*2,y,z,c); end; function b_pred(var t:longint;v:longint):longint; begin if t=0 then exit(-1); if v<=b_key[t] then b_pred:=b_pred(b_left[t],v) else begin b_pred:=b_pred(b_right[t],v); if b_pred=-1 then b_pred:=b_key[t]; end; end; function pred(x,l,r,y:longint):longint; var mid :longint; begin if (t[x].left=l) and (t[x].right=r) then begin pred:=b_pred(t[x].root,y); exit; end; with t[x] do mid:=(left+right) div 2; if mid<l then pred:=pred(x*2+1,l,r,y) else if mid>=r then pred:=pred(x*2,l,r,y) else pred:=max(pred(x*2,l,mid,y),pred(x*2+1,mid+1,r,y)); end; procedure askpred(l,r,x:longint); begin writeln(pred(1,l,r,x)); end; function b_succ(var t:longint;v:longint):longint; begin if t=0 then exit(maxlongint); if v>=b_key[t] then b_succ:=b_succ(b_right[t],v) else begin b_succ:=b_succ(b_left[t],v); if b_succ=maxlongint then b_succ:=b_key[t]; end; end; function succ(x,l,r,y:longint):longint; var mid :longint; begin if (t[x].left=l) and (t[x].right=r) then begin succ:=b_succ(t[x].root,y); exit; end; with t[x] do mid:=(left+right) div 2; if mid<l then succ:=succ(x*2+1,l,r,y) else if mid>=r then succ:=succ(x*2,l,r,y) else succ:=min(succ(x*2,l,mid,y),succ(x*2+1,mid+1,r,y)); end; procedure askselect(a,b,x:longint); var mid :longint; ans :longint; l, r :longint; xx :longint; begin l:=0; r:=1000000000; while l<=r do begin mid:=(l+r) div 2; xx:=rank(1,a,b,mid)+1; if xx<=x then begin ans:=mid; l:=mid+1; end else r:=mid-1; end; if rank(1,a,b,ans)=x then ans:=succ(1,l,r,ans-1) else ans:=ans; writeln(ans); end; procedure asksucc(l,r,x:longint); begin writeln(succ(1,l,r,x)); end; procedure main; var i :longint; k, l, r, x :longint; begin for i:=1 to m do begin read(k); if k=1 then begin read(l,r,x); askrank(l,r,x); end else if k=2 then begin read(l,r,x); askselect(l,r,x); end else if k=3 then begin read(l,x); change(1,l,x,a[l]); a[l]:=x; end else if k=4 then begin read(l,r,x); askpred(l,r,x); end else if k=5 then begin read(l,r,x); asksucc(l,r,x); end; end; end; begin init; main; end.