Luogu Dynamic Ranking (带修改的主席树)
题目大意:
网址:https://www.luogu.org/problemnew/show/2617
给定一个序列a[1]、a[2]、...、a[N],完成M个操作,操作有两种:
[1]Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
[2]C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t。
数据范围: \(1≤n≤10000,1≤m≤10000\)
解法:带修改的主席树:
原本的主席树是维护了一个线段树前缀。
那么前缀有没有想到什么东西? 树状数组\(Bits\)是不是很 ...... ?
那么现在,我们用树状数组套主席树,不就可以实现带修改的可持久化了吗。
具体来说 \(T[1]维护rt[1]\) , \(T[2]维护rt[1]、rt[2]\) , \(T[3]维护rt[3]\) ......
就与树状数组是一样的。
那么现在,两个具体的操作:
修改:
修改需要修改\(logN\)棵主席树,将涉及修改节点的\(log\)个主席树先删后加点即可。
具体来说,修改x位置的,则要修改:for(x; x; x -= (x&-x))Update(rt[x]);
查询:
考虑一下树状数组的查询,是用到了两个前缀相减的方法。
那么这里也是一样的,查询\([L,R]\)就是\([1,R]\)的值减去\([1,(L-1)]\)的值。
具体来说,对于\([L,R]\)区间对应的主席树,每个点的sum值为:
\[Sum[ro] = ∑sum[ro[u]] - ∑sum[ro[v]];u∈[1,R],v∈[1,L-1]\]
那么以查询第区间第\(k\)大为例子,直接将\(k\)与节点的\(Sum\)值比较即可。
总复杂度:
时间复杂度:\(O(NLog^2N)\) , 空间复杂度\(O(NLog^2N)\)
两个去重、二分的函数:
Unique去重函数:
对于a[1]、a[2]、....、a[N],去重函数为:
\[Length = Unique(a+1,a+N+1) - a - 1;\]
Unique函数返回的是 去重后后面第一个空位置,所以要长度减1。
去重完的序列即为a[1]、a[2]、....、a[Length];
Lower_Bound二分函数:
对于序列a[1]、a[2]、....、a[N],查找<=x的最接近数的序列位置,为:
k = lower_bound(a+1,a+N+1,x) - oder;
low_bound返回的是那个值的地址,应该要与第0个位置相减得到其确切的位置。
具体实现代码:
#include<bits/stdc++.h>
#define RG register
#define IL inline
#define maxn 200005
using namespace std;
int N,M,Q,cntl,cntr,lg;
struct Ques{int l,r,k;}qs[maxn];
int rt[2*maxn],ls[20*maxn],rs[20*maxn],sum[20*maxn],tpl[maxn],tpr[maxn];
int a[maxn],oder[2*maxn],cnt;
void Update(int &ro,int l,int r,int ps,int chg){
if(!ro)ro = ++cnt;
sum[ro] += chg;
if(l == r)return;
RG int mid = (l+r)>>1;
if(ps <= mid)Update(ls[ro],l,mid,ps,chg);
else Update(rs[ro],mid+1,r,ps,chg);
}
IL void Modify(RG int ps,RG int chg){
RG int k = lower_bound(oder+1,oder+lg+1,a[ps]) - oder;
for(RG int i = ps; i <= N; i += (i&-i))
Update(rt[i],1,lg,k,chg);
}
int Query(int l,int r,int k){
if(l == r)return l;
RG int mid = (l+r)>>1,Sum = 0;
for(RG int i = 1; i <= cntl; i ++)Sum -= sum[ls[tpl[i]]];
for(RG int i = 1; i <= cntr; i ++)Sum += sum[ls[tpr[i]]];
if(k <= Sum){
for(RG int i = 1; i <= cntl; i ++)tpl[i] = ls[tpl[i]];
for(RG int i = 1; i <= cntr; i ++)tpr[i] = ls[tpr[i]];
return Query(l,mid,k);
}
else{
for(RG int i = 1; i <= cntl; i ++)tpl[i] = rs[tpl[i]];
for(RG int i = 1; i <= cntr; i ++)tpr[i] = rs[tpr[i]];
return Query(mid+1,r,k-Sum);
}
}
IL int Get(RG int l,RG int r,RG int k){
cntl = cntr = 0;
for(RG int i = (l-1); i ; i -= (i&-i))
tpl[++cntl] = rt[i];
for(RG int i = r; i ; i -= (i&-i))
tpr[++cntr] = rt[i];
return Query(1,lg,k);
}
int main(){
freopen("testdate.in","r",stdin);
cin>>N>>M;
for(RG int i = 1; i <= N; i ++)
cin>>a[i] , oder[++lg] = a[i];
char od; int l,r,k;
for(RG int i = 1,c; i <= M; i ++){
cin>>od;
if(od == 'Q')cin>>l>>r>>k,qs[i] = (Ques){l,r,k};
else cin>>l>>k,qs[i] = (Ques){l,0,k},oder[++lg] = k;
}
sort(oder+1,oder+lg+1);
lg = unique(oder+1,oder+lg+1) - oder - 1;
for(RG int i = 1; i <= N; i ++)Modify(i,1);
for(RG int i = 1; i <= M; i ++)
{
if(!qs[i].r){
Modify(qs[i].l , -1);
a[qs[i].l] = qs[i].k;
Modify(qs[i].l , 1);
}
else printf("%d\n",oder[Get(qs[i].l,qs[i].r,qs[i].k)]);
}
return 0;
}
Luogu Dynamic Ranking (带修改的主席树)的更多相关文章
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...
- BZOJ2141排队——树状数组套权值线段树(带修改的主席树)
题目描述 排排坐,吃果果,生果甜嗦嗦,大家笑呵呵.你一个,我一个,大的分给你,小的留给我,吃完果果唱支歌,大家 乐和和.红星幼儿园的小朋友们排起了长长地队伍,准备吃果果.不过因为小朋友们的身高有所区别 ...
- 【带修改的主席树】BZOJ1901-Dynamic Rankings
稍后整理笔记.这题数据范围好像有点问题? #include<iostream> #include<cstdio> #include<cstring> #includ ...
- POJ2104 K-th Number 不带修改的主席树 线段树
http://poj.org/problem?id=2104 给定一个序列,求区间第k小 通过构建可持久化的点,得到线段树左儿子和右儿子的前缀和(前缀是这个序列从左到右意义上的),然后是一个二分的ge ...
- 【poj1901-求区间第k大值(带修改)】树状数组套主席树
901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7025 Solved: 2925[Sub ...
- [Luogu 3701] 「伪模板」主席树
[Luogu 3701] 「伪模板」主席树 这是一道网络流,不是主席树,不是什么数据结构,而是网络流. 题目背景及描述都非常的暴力,以至于 Capella 在做此题的过程中不禁感到生命流逝. S 向 ...
- BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树
题目: emmmm是个权限题 题解: 带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改 修改的时候修改类似树状数组一样进行logn个Insert 查询的时候同理,树状数组的方法 ...
- Dynamic Rankings—带单点修改的主席树
这道题应该是很不错的板子了\(\mathcal{\color{cyan}{Link}}\) \(\mathcal{\color{red}{Description}}\) 给定一个序列,有两种操作.一是 ...
- Dynamic Rankings ZOJ - 2112(主席树+树状数组)
The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with t ...
随机推荐
- fifteen-puzzle
http://www.math.ubc.ca/~cass/courses/m308-02b/projects/grant/fifteen.html http://jamie-wong.com/2011 ...
- 04-PHP-redis
[Redis] 先安装tcl: yum install tcl [下载和安装] 官网http://redis.io/ 下载最新的稳定版本,这里是3.2.0, 然后解压文件并进入. $ sudo ...
- mysql 查找某个表在哪个库
SELECT table_schema FROM information_schema.TABLES WHERE table_name = '表名';
- Lua内存分析工具
最近给公司写了一个lua内存分析工具,可以非常方便的分析出Lua内存泄露问题,有图形化界面操作,方便手机端上传快照等功能 内存分析我是在c语言端写的,也有人写过lua端的分析工具,也蛮好用的,不过lu ...
- 解决java.lang.IllegalArgumentException: No converter found for return value of type: class java.util.ArrayList这个问题
今天使用SSM框架,用@ResponseBody注解,出现了这个问题 java.lang.IllegalArgumentException: No converter found for return ...
- 解析JavaScript函数的多种写法
本文主要分析了JavaScript中函数的几种写法,具体如下: 1.函数的声明和表达式(旧方法,也是最常见的方法) 2.通过Function构造器 这也是一种从一开始就存在方法,但是因为书写麻烦等原因 ...
- MySQL数据库基础(二)(约束以及修改数据表)
一,约束以及修改数据表 约束的作用?1.约束保证数据的完整性.一致性:2.约束分为表级约束.列级约束:3.约束类型包括:NOT NULL(非空约束).PRIMARY KEY(主键约束).UNIQUE ...
- 【学习笔记】Spring中的BeanFactory和ApplicationContext 以及 Bean的生命周期(Y2-3-2)
BeanFactory和ApplicationContext Spring的IoC容器就是一个实现了BeanFactory接口的可实例化类. Spring提供了两种不同的容器: 一种是最基本的Bean ...
- win10+anaconda+cuda配置dlib,使用GPU对dlib的深度学习算法进行加速(以人脸检测为例)
在计算机视觉和机器学习方向有一个特别好用但是比较低调的库,也就是dlib,与opencv相比其包含了很多最新的算法,尤其是深度学习方面的,因此很有必要学习一下.恰好最近换了一台笔记本,内含一块GTX1 ...
- puppeteer,新款headless chrome!
puppeteer puppeteer是一种谷歌开发的Headless Chrome,因为puppeteer的出现,业内许多自动化测试库停止维护,比如PhantomJS,Selenium IDE fo ...