博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
bzoj 1901 线段树套平衡树+二分答案查询
阅读量:6000 次
发布时间:2019-06-20

本文共 5347 字,大约阅读时间需要 17 分钟。

我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案,

查询每个二分到的mid在这个区间里的rank,然后就行了

/**************************************************************    Problem: 1901    User: BLADEVIL    Language: Pascal    Result: Accepted    Time:3220 ms    Memory:6592 kb****************************************************************/ //By BLADEVILtype    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
mid then change(x*2+1,y,z) else change(x*2,y,z);end; function ask(x,l,r,k:longint):longint;var mid :longint;begin ask:=0; if (t[x].left=l) and (t[x].right=r) then begin ask:=rank(t[x].root,k); exit; end; with t[x] do mid:=(left+right) div 2; if mid
=r then ask:=ask(x*2,l,r,k) else ask:=ask(x*2,l,mid,k)+ask(x*2+1,mid+1,r,k);end; function succ(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; function ask_succ(x,l,r,y:longint):longint;var mid :longint;begin if (t[x].left=l) and (t[x].right=r) then begin ask_succ:=succ(t[x].root,y); if ask_succ=-1 then ask_succ:=maxlongint; exit; end; with t[x] do mid:=(left+right) div 2; if l>mid then ask_succ:=ask_succ(x*2+1,l,r,y) else if r<=mid then ask_succ:=ask_succ(x*2,l,r,y) else ask_succ:=min(ask_succ(x*2,l,mid,y),ask_succ(x*2+1,mid+1,r,y));end; function ask_pred(x,l,r,y:longint):longint;var mid :longint;begin if (t[x].left=l) and (t[x].right=r) then begin ask_pred:=pred(t[x].root,y); exit; end; with t[x] do mid:=(left+right) div 2; if l>mid then ask_pred:=ask_pred(x*2+1,l,r,y) else if r<=mid then ask_pred:=ask_pred(x*2,l,r,y) else ask_pred:=max(ask_pred(x*2,l,mid,y),ask_pred(x*2+1,mid+1,r,y));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; xx:=ask(1,x,y,mid); if xx>=k-1 then begin ans:=mid; r:=mid-1; end else l:=mid+1; end; if ask(1,x,y,ans)<>k-1 then xx:=ask_pred(1,x,y,ans-1) else xx:=ask_succ(1,x,y,ans); writeln(xx);end; procedure init;var i :longint;begin read(n,m); for i:=1 to n do read(a[i]); readln; build(1,1,n);end; procedure main;var i :longint; ch :char; l, r, x :longint; begin for i:=1 to m do begin read(ch); if ch='Q' then begin readln(l,r,x); query(l,r,x); end else begin readln(l,x); change(1,l,x); a[l]:=x; end; end;end; begin init; main;end.

 

转载于:https://www.cnblogs.com/BLADEVIL/p/3455336.html

你可能感兴趣的文章
Lesson23 DMA操作
查看>>
find 命令总结
查看>>
安装系统时不小心分区了,别的盘的数据怎样恢复
查看>>
Saltstack-4:数据系统pillar
查看>>
我的设计模式:从模版设计模式谈到建造者模式
查看>>
RIP动态路由协议配置思路及原理
查看>>
修改防火墙策略设置
查看>>
免费OA的选型遵循的原则
查看>>
京东到家基于netty与websocket的实践
查看>>
对新入门程序员,有用的几点建议!
查看>>
计算机二级报名步骤
查看>>
iphone 6s pp助手 越狱
查看>>
用BCV备份Oracle数据库
查看>>
Oracle 常用的dump
查看>>
下载源代码编译安装
查看>>
psql无法执行 和启动报错
查看>>
lua 简单实现 面向对象
查看>>
如何更改SVN 用户名
查看>>
条件语句练习-比分预测
查看>>
货物管理系统(数据结构顺序表)
查看>>