首页 > 代码库 > BZOJ 3196
BZOJ 3196
program bzoj3196;const inf=100000000; maxn=200001; maxm=3000001;var n,m,time,temp:longint; root,a:array [0..maxn] of longint; left,right,rnd,v,s,w:array [0..maxm] of longint;procedure update(now:longint);begin s[now]:=s[left[now]]+s[right[now]]+w[now];end;procedure rightturn(var now:longint);var t:longint;begin t:=left[now]; left[now]:=right[t]; right[t]:=now; s[t]:=s[now]; update(now); now:=t;end;procedure leftturn(var now:longint);var t:longint;begin t:=right[now]; right[now]:=left[t]; left[t]:=now; s[t]:=s[now]; update(now); now:=t;end;procedure insert(var now:longint; num:longint);begin if now=0 then begin inc(time); now:=time; w[now]:=1; s[now]:=w[now]; v[now]:=num; rnd[now]:=random(inf); exit; end; inc(s[now]); if num=v[now] then inc(w[now]) else if num<v[now] then begin insert(left[now],num); if rnd[left[now]]<rnd[now] then rightturn(now); end else begin insert(right[now],num); if rnd[right[now]]<rnd[now] then leftturn(now); end;end;procedure del(var now:longint; num:longint);begin if v[now]=num then begin if w[now]>1 then begin dec(w[now]); dec(s[now]); exit; end; if left[now]*right[now]=0 then now:=left[now]+right[now] else if rnd[left[now]]<rnd[right[now]] then begin rightturn(now); del(now,num); end else begin leftturn(now); del(now,num); end end else if num<v[now] then begin del(left[now],num); dec(s[now]); end else begin del(right[now],num); dec(s[now]); end;end;procedure build(now,l,r,x,num:longint);var mid:longint;begin insert(root[now],num); if l=r then exit; mid:=(l+r) shr 1; if x<=mid then build(now<<1,l,mid,x,num) else build(now<<1 or 1,mid+1,r,x,num);end;procedure ask_rank(now,num:longint);begin if now=0 then exit; if num=v[now] then begin inc(temp,s[left[now]]); exit; end else if num<v[now] then ask_rank(left[now],num) else begin inc(temp,s[left[now]]+w[now]); ask_rank(right[now],num); end;end;procedure get_rank(now,l,r,x,y,num:longint);var mid:longint;begin mid:=(l+r) shr 1; if (l=x) and (r=y) then begin ask_rank(root[now],num); exit; end; if mid>=y then get_rank(now<<1,l,mid,x,y,num) else if mid<x then get_rank(now<<1 or 1,mid+1,r,x,y,num) else begin get_rank(now<<1,l,mid,x,mid,num); get_rank(now<<1 or 1,mid+1,r,mid+1,y,num); end;end;procedure get_index(x,y,z:longint);var l,r,ans,mid:longint;begin l:=0; r:=inf; while l<=r do begin mid:=(l+r) shr 1; temp:=1; get_rank(1,1,n,x,y,mid); if temp<=z then begin l:=mid+1; ans:=mid; end else r:=mid-1; end; writeln(ans);end;procedure change(now,l,r,x,num,y:longint);var mid:longint;begin del(root[now],y); insert(root[now],num); if l=r then exit; mid:=(l+r) shr 1; if x<=mid then change(now<<1,l,mid,x,num,y) else change(now<<1 or 1,mid+1,r,x,num,y);end;function max(x,y:longint):longint;begin if x>y then exit(x) else exit(y);end;function min(x,y:longint):longint;begin if x<y then exit(x) else exit(y);end;procedure before(now,num:longint);begin if now=0 then exit; if v[now]<num then begin temp:=max(v[now],temp); before(right[now],num); end else before(left[now],num);end;procedure after(now,num:longint);begin if now=0 then exit; if v[now]>num then begin temp:=min(v[now],temp); after(left[now],num); end else after(right[now],num);end;procedure ask_after(now,l,r,x,y,num:longint);var mid:longint;begin if (l=x) and (r=y) then begin after(root[now],num); exit; end; mid:=(l+r) shr 1; if mid>=y then ask_after(now<<1,l,mid,x,y,num) else if mid<x then ask_after(now<<1 or 1,mid+1,r,x,y,num) else begin ask_after(now<<1,l,mid,x,mid,num); ask_after(now<<1 or 1,mid+1,r,mid+1,y,num); end;end;procedure ask_before(now,l,r,x,y,num:longint);var mid:longint;begin if (l=x) and (r=y) then begin before(root[now],num); exit; end; mid:=(l+r) shr 1; if mid>=y then ask_before(now<<1,l,mid,x,y,num) else if mid<x then ask_before(now<<1 or 1,mid+1,r,x,y,num) else begin ask_before(now<<1,l,mid,x,mid,num); ask_before(now<<1 or 1,mid+1,r,mid+1,y,num); end;end;procedure main;var i,x,y,now,f:longint;begin read(n,m); for i:=1 to n do read(a[i]); for i:=1 to n do build(1,1,n,i,a[i]); for i:=1 to m do begin read(f); case f of 1: begin read(x,y,now); temp:=1; get_rank(1,1,n,x,y,now); writeln(temp); end; 2: begin read(x,y,now); get_index(x,y,now); end; 3: begin read(x,y); change(1,1,n,x,y,a[x]); a[x]:=y; end; 4: begin read(x,y,now); temp:=0; ask_before(1,1,n,x,y,now); writeln(temp); end; 5: begin read(x,y,now); temp:=inf; ask_after(1,1,n,x,y,now); writeln(temp); end; end; end;end;begin main;end.
BZOJ 3196
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。