bzoj 1901 线段树套平衡树+二分答案查询
我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案,
查询每个二分到的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 线段树套平衡树+二分答案查询的更多相关文章
- bzoj 2120 线段树套平衡树
先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
- bzoj 2141 线段树套平衡树
用树套树来解决这个问题,存储每个节点的数值是多少,然后交换 对于答案的变更可以讨论下,假设交换的是x,y位置的数x<=y 如果x=y || high[x]=high[y]则对答案没有影响 如果h ...
- BZOJ 3196 线段树套平衡树
(代码无比丑陋) //By SiriusRen #include <cstdio> #include <algorithm> using namespace std; int ...
- [BZOJ1146][CTSC2008]网络管理Network(二分+树链剖分+线段树套平衡树)
题意:树上单点修改,询问链上k大值. 思路: 1.DFS序+树状数组套主席树 首先按照套路,关于k大值的问题,肯定要上主席树,每个点维护一棵权值线段树记录它到根的信息. 关于询问,就是Que(u)+Q ...
- bzoj 3196/ Tyvj 1730 二逼平衡树 (线段树套平衡树)
3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description ...
- 浅谈树套树(线段树套平衡树)&学习笔记
0XFF 前言 *如果本文有不好的地方,请在下方评论区提出,Qiuly感激不尽! 0X1F 这个东西有啥用? 树套树------线段树套平衡树,可以用于解决待修改区间\(K\)大的问题,当然也可以用 ...
- BZOJ3196二逼平衡树——线段树套平衡树(treap)
此为平衡树系列最后一道:二逼平衡树您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名2.查询区间内排名为k的值3.修改某一位值上的数值4.查询 ...
- P3380 【模板】二逼平衡树(树套树)(线段树套平衡树)
P3380 [模板]二逼平衡树(树套树) 前置芝士 P3369 [模板]普通平衡树 线段树套平衡树 这里写的是线段树+splay(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...
随机推荐
- 用gradle编译任意结构的Android项目
## 需求 * 继续用`Eclipse`项目的结构,但是使用`gradle`编译,或者说任意的项目结构进行编译. ## 解决方案 1. Android studio的项目结构 1. Android S ...
- Python 3基础教程23-多维列表
这里简单举例一个多维列表,多维看起来都很晕. # 多维列表 x = [ [5,6],[6,7],[7,2] ,[2,5] ,[4,9]] print(x) # 根据索引引用列表元素,例如打印[6,7] ...
- 常见bug解析-移动端
手机测试常见bug解析 1.测试时遇到“手机无响应”? 有以下几个原因: a.手机内存不足 b.android进程之间死锁引起的(就是两个进程之间) c.手机的CPU运行高引起的 可以查看手机的崩溃日 ...
- linux 查看文件空间大小
1. 查看总的空间占用情况:df -hl 2.查看linux系统里面的各个目录.文件夹的大小和使用情况, 先切换到需要查看的目录,如果需要查看所有linux目录的使用情况就直接切换到系统跟目录,然后执 ...
- asp.net应用程序脱机app_offline.htm文件
This application is currently offline. To enable the application, remove the app_offline.htm file fr ...
- nginx开机自启动
配置步骤:1 . vi /etc/init.d/nginx2. chkconfig --level nginx 2345 on --重点 --------------------以下为nginx配置文 ...
- Spark+Python+Pycharm在Windows下的配置
http://blog.csdn.net/ydq1206/article/details/51922148
- ES mapping的写入与查看
Elasticsearch索引mapping的写入.查看与修改 https://blog.csdn.net/napoay/article/details/52012249 首先创建一个索引: curl ...
- CHM格式的电子书打开是空白的解决办法
CHM是英语“Compiled Help Manual”的简写,即“已编译的帮助文件”.CHM是微软新一代的帮助文件格式,利用HTML作源文,把帮助内容以类似数据库的形式编译储存.
- 51nod 1565模糊搜索(FFT)
题目大意就是字符串匹配,不过有一个门限k而已 之前有提到过fft做字符串匹配,这里和之前那种有些许不同 因为只有A,C,G,T四种字符,所以就考虑构造4个01序列 例如,模板串a关于'A'的01序列中 ...