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

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

/**************************************************************
Problem:
User: BLADEVIL
Language: Pascal
Result: Accepted
Time: ms
Memory: kb
****************************************************************/ //By BLADEVIL
type
rec =record
left, right, root :longint;
end; var
n, m :longint;
a :array[..] of longint;
t :array[..] of rec;
bt :array[..] of longint;
b_size, b_left, b_right :array[..] of longint;
b_key :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 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]]+;
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]]+;
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= 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_right[t]=) and (v>b_key[t])
or (b_left[t]=) and (v<b_key[t]) then
begin
delete:=b_key[t];
if (b_left[t]=) or (b_right[t]=) then
t:=b_right[t]+b_left[t] else
b_key[t]:=delete(b_left[t],v+);
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= then exit();
if v<=b_key[t] then rank:=rank(b_left[t],v) else
rank:=rank(b_right[t],v)+b_size[b_left[t]]+;
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;
mid:=(l+r) div ;
build(x*,l,mid); build(x*+,mid+,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 ;
if y>mid then change(x*+,y,z) else change(x*,y,z);
end; function ask(x,l,r,k:longint):longint;
var
mid :longint;
begin
ask:=;
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 ;
if mid<l then ask:=ask(x*+,l,r,k) else
if mid>=r then ask:=ask(x*,l,r,k) else
ask:=ask(x*,l,mid,k)+ask(x*+,mid+,r,k);
end; function succ(var t:longint;v:longint):longint;
begin
if t= then exit(-);
if b_key[t]<v then succ:=succ(b_right[t],v) else
begin
succ:=succ(b_left[t],v);
if succ=- then succ:=b_key[t];
end;
end; function pred(var t:longint;v:longint):longint;
begin
if t= then exit(-);
if b_key[t]>v then pred:=pred(b_left[t],v) else
begin
pred:=pred(b_right[t],v);
if pred=- 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=- then ask_succ:=maxlongint;
exit;
end;
with t[x] do mid:=(left+right) div ;
if l>mid then ask_succ:=ask_succ(x*+,l,r,y) else
if r<=mid then ask_succ:=ask_succ(x*,l,r,y) else
ask_succ:=min(ask_succ(x*,l,mid,y),ask_succ(x*+,mid+,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 ;
if l>mid then ask_pred:=ask_pred(x*+,l,r,y) else
if r<=mid then ask_pred:=ask_pred(x*,l,r,y) else
ask_pred:=max(ask_pred(x*,l,mid,y),ask_pred(x*+,mid+,r,y));
end; procedure query(x,y,k:longint);
var
l, r, mid :longint;
ans :longint;
xx :longint;
begin
l:=; r:=;
while l<=r do
begin
mid:=(l+r) div ;
xx:=ask(,x,y,mid);
if xx>=k- then
begin
ans:=mid;
r:=mid-;
end else l:=mid+;
end;
if ask(,x,y,ans)<>k- then
xx:=ask_pred(,x,y,ans-) else
xx:=ask_succ(,x,y,ans);
writeln(xx);
end; procedure init;
var
i :longint;
begin
read(n,m);
for i:= to n do read(a[i]);
readln;
build(,,n);
end; procedure main;
var
i :longint;
ch :char;
l, r, x :longint; begin
for i:= 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(,l,x);
a[l]:=x;
end;
end;
end; begin
init;
main;
end.

bzoj 1901 线段树套平衡树+二分答案查询的更多相关文章

  1. bzoj 2120 线段树套平衡树

    先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...

  2. 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...

  3. bzoj 2141 线段树套平衡树

    用树套树来解决这个问题,存储每个节点的数值是多少,然后交换 对于答案的变更可以讨论下,假设交换的是x,y位置的数x<=y 如果x=y || high[x]=high[y]则对答案没有影响 如果h ...

  4. BZOJ 3196 线段树套平衡树

    (代码无比丑陋) //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int ...

  5. [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)

    题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...

  6. bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description ...

  7. 浅谈树套树(线段树套平衡树)&学习笔记

    0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...

  8. BZOJ3196二逼平衡树——线段树套平衡树(treap)

    此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...

  9. P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)

    P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...

随机推荐

  1. [转]Visual Studio 项目类型 GUID 清单

    转自:https://www.codeproject.com/Reference/720512/List-of-Visual-Studio-Project-Type-GUIDs Complete li ...

  2. 一步一步构建手机WebApp开发——环境搭建篇

    从2007年,乔布斯带来了第一代Iphone手机,整个移动互联网发生天翻地覆的变化,也同时证明了乔布斯的一句名言:“再一次改变世界”. 在当今的移动互联网,手机App居多,很多App对移动设备的要求也 ...

  3. 第三篇 Fiddler数据包分析

    上一篇博文写完了Fiddler的配置,本篇讲讲如何用Fiddler进行数据包的分析,下图是抓到的数据包区域,对这些区域的可见字段进行解析如下, 以便了解这些字段的含义 1.  了解数据包区域的字段含义 ...

  4. CSP201409-1:相邻数对

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  5. ardupilot_gazebo仿真(二)

    ardupilot_gazebo仿真(二) 标签(空格分隔): 未分类 在模型中添加sensor gezebo官网-sensor部分教程 gezebo官网-基础部分教程 Gazebo plugins ...

  6. mysql 数据库新增用户

    1.user表中host为%含义: Host列指定了允许用户登录所使用的IP,比如user=root Host=192.168.1.1.这里的意思就是说root用户只能通过192.168.1.1的客户 ...

  7. 编程练习:寻找发帖"水王"扩展问题二

    回顾 在前面两篇文章已经实现了水王id出现次数超过一半,以及水王id出现次数刚好一半 分析 借助上面水王id出现次数刚好出现一半的分析,其实这里就是找出数组中出现次数前三的元素,具体的分析,见前面两篇 ...

  8. 【python】 json.dumps() json.dump()的区别

    以前写的很简单,只有几句话,最近发现本文是本博客阅读量最大的一篇文章,觉得这样有种把人骗进来的感觉,于是又细化了一些.如果还有不好的地方,欢迎指出. 首先说明基本功能: dumps是将dict转化成s ...

  9. Hibernate配置文件说明

    <property name="hbm2ddl.auto">create</property> create - 启动Hibernate前先删除表,重新创建 ...

  10. Java的sql语句 写关键字不需要添加单引号

    Java的sql语句 写关键字不需要添加单引号