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[..] of longint;
t :array[..] of rec;
b_left, b_right, b_key :array[..] of longint;
b_size :array[..] 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]]+;
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]]+;
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= then
begin
inc(tot);
t:=tot;
b_left[t]:=;
b_right[t]:=;
b_size[t]:=;
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]=) or (b_key[t]>v) and (b_left[t]=) then
begin
delete:=b_key[t];
if (b_left[t]=) or (b_right[t]=) then
t:=b_left[t]+b_right[t] else
b_key[t]:=delete(b_left[t],v+);
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:=;
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 ;
build(x*,l,mid); build(x*+,mid+,r);
end; function b_rank(var t:longint;v:longint):longint;
begin
if t= then exit();
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]]+;
end; procedure init;
var
i :longint; begin
read(n,m);
for i:= to n do read(a[i]);
build(,,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 ;
if mid<l then rank:=rank(x*+,l,r,y) else
if mid>=r then rank:=rank(x*,l,r,y) else
rank:=rank(x*,l,mid,y)+rank(x*+,mid+,r,y);
end; procedure askrank(l,r,x:longint);
begin
writeln(rank(,l,r,x)+);
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 ;
if y>mid then change(x*+,y,z,c) else
change(x*,y,z,c);
end; function b_pred(var t:longint;v:longint):longint;
begin
if t= then exit(-);
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=- 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 ;
if mid<l then pred:=pred(x*+,l,r,y) else
if mid>=r then pred:=pred(x*,l,r,y) else
pred:=max(pred(x*,l,mid,y),pred(x*+,mid+,r,y));
end; procedure askpred(l,r,x:longint);
begin
writeln(pred(,l,r,x));
end; function b_succ(var t:longint;v:longint):longint;
begin
if t= 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 ;
if mid<l then succ:=succ(x*+,l,r,y) else
if mid>=r then succ:=succ(x*,l,r,y) else
succ:=min(succ(x*,l,mid,y),succ(x*+,mid+,r,y));
end; procedure askselect(a,b,x:longint);
var
mid :longint;
ans :longint;
l, r :longint;
xx :longint;
begin
l:=; r:=;
while l<=r do
begin
mid:=(l+r) div ;
xx:=rank(,a,b,mid)+;
if xx<=x then
begin
ans:=mid;
l:=mid+;
end else r:=mid-;
end;
if rank(,a,b,ans)=x then ans:=succ(,l,r,ans-) else ans:=ans;
writeln(ans);
end; procedure asksucc(l,r,x:longint);
begin
writeln(succ(,l,r,x));
end; procedure main;
var
i :longint;
k, l, r, x :longint; begin
for i:= to m do
begin
read(k);
if k= then
begin
read(l,r,x);
askrank(l,r,x);
end else
if k= then
begin
read(l,r,x);
askselect(l,r,x);
end else
if k= then
begin
read(l,x);
change(,l,x,a[l]);
a[l]:=x;
end else
if k= then
begin
read(l,r,x);
askpred(l,r,x);
end else
if k= then
begin
read(l,r,x);
asksucc(l,r,x);
end;
end;
end; begin
init;
main;
end.
bzoj 3196二逼平衡树 线段树套平衡树的更多相关文章
- BZOJ3196二逼平衡树——线段树套平衡树(treap)
此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...
- bzoj3196 二逼平衡树——线段树套平衡树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3196 人生中第一棵树套树! 写了一个晚上,成功卡时 9000ms+ 过了! 很要注意数组的大 ...
- [bzoj3196]Tyvj 1730 二逼平衡树——线段树套平衡树
题目 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查 ...
- P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)
P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...
- bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description ...
- 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2271 Solved: 935[Submit][Stat ...
- P3380 【模板】二逼平衡树(树套树) 线段树套平衡树
\(\color{#0066ff}{ 题目描述 }\) 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 查询k在区间内的排名 查询区间内排名为k的值 修改某一位值上 ...
- BZOJ3196 二逼平衡树 【线段树套平衡树】
题目 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间内排名为k的值 3.修改某一位值上的数值 4.查询k在区间内的前驱(前驱 ...
- BZOJ 3196 二逼平衡树
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询k在区间内的 ...
随机推荐
- VectorDrawable在Android中的配置
一.让Android支持VectorDrawable apply plugin: 'com.android.application' android { defaultConfig { vectorD ...
- 步骤1:JMeter 录制脚本接口测试
JMeter 常用测试方法简介 1.下载安装 http://jmeter.apache.org/download_jmeter.cgi 安装JDK,配置环境变量JAVA_HOME. 系统要求:JMet ...
- Qt Qwdget 汽车仪表知识点拆解7 图像绘制,旋转
先贴上效果图,注意,没有写逻辑,都是乱动的 看下最中心的指针旋转,这里使用的QPainter的绘制函数 要显示复杂的效果,需要分层 void Widget::draw_number_pointer() ...
- Lambda表达式在Kotlin中怎样工作的:setOnClickListener的转换(KAD 18)
作者:Antonio Leiva 时间:Mar 28, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin-android/ 虽然,我在其它文章讲过一点 ...
- bug单的提交
顶头信息 所属产品,所属项目,所属模块,影响版本,当前指派,bug类型:代码错误,界面优化,设计缺陷,性能问题,标准规范,其他,安全相关.bug标题,严重程度,优先级 缺陷描述 bug描述,预置条件, ...
- 第七篇Python基本数据类型之数字&字符串&布尔值
数字 写在最前,必须要会的:int() 整型 Python3里无论数字多长都用int表示,Python2里有int和Long表示,Long表示长整型 有关数字的常用方法,方法调用后面都必须带括号() ...
- Spark搭档Elasticsearch
Spark与elasticsearch结合使用是一种常用的场景,小编在这里整理了一些Spark与ES结合使用的方法.一. write data to elasticsearch利用elasticsea ...
- C++STL——list
一.相关定义 list 链表,分配的内存不连续 可以高效地进行插入/删除元素 不可随机访问,访问速度慢 特征 只能通过迭代器来访问list中的元素 在头和尾都可以插入元素 二.list [前提条件] ...
- 团队项目-第十次scrum 会议
时间:11.6 时长:20分钟 地点:主235教室走廊 工作情况 团队成员 已完成任务 待完成任务 解小锐 完成多种招聘方式的逻辑编写 陈鑫 实现游戏的存档功能 李金奇 添加多种招聘方式等功能 王辰昱 ...
- lincode-58-四数之和
58-四数之和 给一个包含n个数的整数数组S,在S中找到所有使得和为给定整数target的四元组(a, b, c, d). 注意事项 四元组(a, b, c, d)中,需要满足a <= b &l ...