## bzoj 1901 线段树套平衡树+二分答案查询

/**************************************************************
Problem: 1901
Language: Pascal
Result: Accepted
Time:3220 ms
Memory:6592 kb
****************************************************************/

type
rec                     =record
left, right, root   :longint;
end;

var
n, m                    :longint;
a                       :array[0..10010] of longint;
t                       :array[0..40010] of rec;
bt                      :array[0..300000] of longint;
b_size, b_left, b_right :array[0..300000] of longint;
b_key                   :array[0..300000] 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 rotate_right(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_right[t]]+b_size[b_left[t]]+1;
t:=k;
end;

procedure rotate_left(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_right[t]]+b_size[b_left[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
rotate_right(b_left[t]) else
if b_size[b_right[b_left[t]]]>b_size[b_right[t]] then
begin
rotate_left(b_left[t]);
rotate_right(t);
end else exit;
end else
begin
if b_size[b_right[b_right[t]]]>b_size[b_left[t]] then
rotate_left(b_right[t]) else
if b_size[b_left[b_right[t]]]>b_size[b_left[t]] then
begin
rotate_right(b_right[t]);
rotate_left(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_right[t]=0) and (v>b_key[t])
or (b_left[t]=0) and (v<b_key[t]) then
begin
delete:=b_key[t];
if (b_left[t]=0) or (b_right[t]=0) then
t:=b_right[t]+b_left[t] else
b_key[t]:=delete(b_left[t],v+1);
end else
if v<b_key[t] then delete:=delete(b_left[t],v) else
delete:=delete(b_right[t],v);
end;

function rank(var t:longint; v:longint):longint;
begin
if t=0 then exit(0);
if v<=b_key[t] then rank:=rank(b_left[t],v) else
rank:=rank(b_right[t],v)+b_size[b_left[t]]+1;
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;
mid:=(l+r) div 2;
build(x*2,l,mid); build(x*2+1,mid+1,r);
end;

procedure change(x,y,z:longint);
var
mid                     :longint;
begin
mid:=delete(t[x].root,a[y]);
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) else change(x*2,y,z);
end;

var
mid                     :longint;
begin
if (t[x].left=l) and (t[x].right=r) then
begin
exit;
end;
with t[x] do mid:=(left+right) div 2;
end;

function succ(var t:longint;v:longint):longint;
begin
if t=0 then exit(-1);
if b_key[t]<v then succ:=succ(b_right[t],v) else
begin
succ:=succ(b_left[t],v);
if succ=-1 then succ:=b_key[t];
end;
end;

function pred(var t:longint;v:longint):longint;
begin
if t=0 then exit(-1);
if b_key[t]>v then pred:=pred(b_left[t],v) else
begin
pred:=pred(b_right[t],v);
if pred=-1 then pred:=b_key[t];
end;
end;

var
mid                     :longint;
begin
if (t[x].left=l) and (t[x].right=r) then
begin
exit;
end;
with t[x] do mid:=(left+right) div 2;
end;

var
mid                     :longint;
begin
if (t[x].left=l) and (t[x].right=r) then
begin
exit;
end;
with t[x] do mid:=(left+right) div 2;
end;

procedure query(x,y,k:longint);
var
l, r, mid               :longint;
ans                     :longint;
xx                      :longint;
begin
l:=1; r:=1000000000;
while l<=r do
begin
mid:=(l+r) div 2;
if xx>=k-1 then
begin
ans:=mid;
r:=mid-1;
end else l:=mid+1;
end;
writeln(xx);
end;

procedure init;
var
i                       :longint;
begin
for i:=1 to n do read(a[i]);
build(1,1,n);
end;

procedure main;
var
i                       :longint;
ch                      :char;
l, r, x                 :longint;

begin
for i:=1 to m do
begin
if ch='Q' then
begin
query(l,r,x);
end else
begin
change(1,l,x);
a[l]:=x;
end;
end;
end;

begin
init;
main;
end.

posted on 2013-12-03 10:57  BLADEVIL  阅读(...)  评论(...编辑  收藏

• 随笔 - 244
• 文章 - 0
• 评论 - 12