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(不吸氧竟然卡过了) 对线段树的每个节点都维护一颗平衡树 每次把给定区间 ...
随机推荐
- Qt用委托绘制需要的图形的步骤
1.拷贝一份option: QStyleOptionViewItemV4 opt = option; 2.获取到widget,也是通过QStyleOptionViewItem &option ...
- fidder工具学习抓取Firefox包
fidder抓取Firefox的https请求 抓包之前需要设置fidder,我下面的截图是fidder4,打开fidder—>Tools—>Options如图: 选择https,勾选所有 ...
- 第八篇Python基本数据类型之列表、元组与字典
列表 写在最前,必须要会的:append(),extend(),insert(),索引,切片,循环 list 是一个类,是个对象 列表用 方括号[]括起来的,[]内以逗号分割每个元素,列表中的元素可 ...
- python 基础篇 12 装饰器进阶
本节主要内容:1. 通⽤装饰器回顾2. 函数的有⽤信息3. 带参数的装饰器4. 多个装饰器同时装饰⼀个函数 ⼀. 通⽤装饰器的回顾开闭原则: 对增加功能开放. 对修改代码封闭装饰器的作⽤: 在不改变原 ...
- HDFS分布式集群
一.HDFS伪分布式环境搭建 Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统.它和现有的分布式文件系统有很多共同点.但同时, ...
- 论文翻译_Tracking The Untrackable_Learning To Track Multiple Cues with Long-Term Dependencies_IEEE2017
Tracking The Untrackable: Learning to Track Multiple Cues with Long-Term Dependencies 跟踪不可跟踪:学习跟踪具有长 ...
- Python 3 学习笔记之——面向对象
1. 类的介绍 类(Class) 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例,类是对象的抽象. 方法:类中定义的函数. 类变量:类变量在整个实 ...
- cmd命令笔记
查看端口信息:netstat -ano eg. netstat -ano|findstr 0.0.0.0:443 根据pid查看进程信息等:wmic process get name,executab ...
- Drools 7.4.1.Final参考手册(八) 规则语言参考
规则语言参考 概述 Drools有一个“本地”的规则语言.这种格式在标点符号上非常轻,并且通过“扩展器”支持自然语言和领域特定的语言,使语言能够变形到您的问题领域.本章主要与本机规则格式一致.用于表示 ...
- HDU 1693 Eat the Trees(插头DP,入门题)
Problem Description Most of us know that in the game called DotA(Defense of the Ancient), Pudge is a ...