【洛谷P2617】Dynamic Rankings
题目大意:维护带修改区间 K 小值。
题解:学习到了树状数组套权值线段树。
主席树,即:可持久化权值线段树,支持维护静态区间的 K 小值问题,其核心思想是维护 N 棵权值线段树,每个线段树维护的是序列 [1,i] 的权值,并根据可持久化思想使得空间复杂度维持在 \(O(nlogn)\)。
树状数组套权值线段树,支持维护带修改区间 K 小值的问题,其核心思想是改变静态主席树中各个权值线段树的前缀和处理方式,在这里采用树状数组中的前缀和处理方式,平衡了修改和查询的时间和空间。时间和空间复杂度为 \(O(nlognlogn)\)。注意:这里 log 是以 2 为底的对数。1e5 的 log2 大约为16,因此内存开 300 倍。
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
inline int read(){
int x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
char opt[5];
int n,m,a[maxn],tmp[2][20],cnt[2];
int d[maxn<<1],len;
struct operation{bool tag;int l,r,k;int pos,val;}q[maxn];
struct node{
#define ls(x) t[x].lc
#define rs(x) t[x].rc
int lc,rc,sum;
}t[maxn*300];
int tot,root[maxn];
inline void pushup(int o){t[o].sum=t[ls(o)].sum+t[rs(o)].sum;}
void insert(int &o,int l,int r,int pos,int val){
if(!o)o=++tot;
if(l==r){t[o].sum+=val;return;}
int mid=l+r>>1;
if(pos<=mid)insert(ls(o),l,mid,pos,val);
else insert(rs(o),mid+1,r,pos,val);
pushup(o);
}
int query(int l,int r,int k){
if(l==r)return l;
int mid=l+r>>1;
int lsize=0;
for(int i=1;i<=cnt[1];i++)lsize+=t[ls(tmp[1][i])].sum;
for(int i=1;i<=cnt[0];i++)lsize-=t[ls(tmp[0][i])].sum;
if(k<=lsize){
for(int i=1;i<=cnt[1];i++)tmp[1][i]=ls(tmp[1][i]);
for(int i=1;i<=cnt[0];i++)tmp[0][i]=ls(tmp[0][i]);
return query(l,mid,k);
}else{
for(int i=1;i<=cnt[1];i++)tmp[1][i]=rs(tmp[1][i]);
for(int i=1;i<=cnt[0];i++)tmp[0][i]=rs(tmp[0][i]);
return query(mid+1,r,k-lsize);
}
}
inline int lowbit(int x){return x&-x;}
inline void add(int x,int val){
int pos=lower_bound(d+1,d+len+1,a[x])-d;
for(int i=x;i<=n;i+=lowbit(i))insert(root[i],1,len,pos,val);
}
int querykth(int l,int r,int k){
memset(tmp,0,sizeof(tmp)),cnt[1]=cnt[0]=0;
for(int i=r;i;i-=lowbit(i))tmp[1][++cnt[1]]=root[i];
for(int i=l-1;i;i-=lowbit(i))tmp[0][++cnt[0]]=root[i];
return query(1,len,k);
}
void read_and_parse(){
n=read(),m=read();
for(int i=1;i<=n;i++)d[++len]=a[i]=read();
for(int i=1;i<=m;i++){
scanf("%s",opt);
if(opt[0]=='Q')q[i].tag=0,q[i].l=read(),q[i].r=read(),q[i].k=read();
else q[i].tag=1,q[i].pos=read(),d[++len]=q[i].val=read();
}
sort(d+1,d+len+1);
len=unique(d+1,d+len+1)-d-1;
for(int i=1;i<=n;i++)add(i,1);
}
void solve(){
for(int i=1;i<=m;i++){
if(q[i].tag){
add(q[i].pos,-1);
a[q[i].pos]=q[i].val;
add(q[i].pos,1);
}else{
printf("%d\n",d[querykth(q[i].l,q[i].r,q[i].k)]);
}
}
}
int main(){
read_and_parse();
solve();
return 0;
}
【洛谷P2617】Dynamic Rankings的更多相关文章
- 洛谷P2617 Dynamic Rankings (主席树)
洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...
- 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)
P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...
- 洛谷 P2617 Dynamic Rankings 解题报告
P2617 Dynamic Rankings 题目描述 给定一个含有\(n\)个数的序列\(a[1],a[2],a[3],\dots,a[n]\),程序必须回答这样的询问:对于给定的\(i,j,k\) ...
- 洛谷 P2617 Dynamic Rankings || ZOJ - 2112
写的让人看不懂,仅留作笔记 静态主席树,相当于前缀和套(可持久化方法构建的)值域线段树. 建树方法:记录前缀和的各位置的线段树的root.先建一个"第0棵线段树",是完整的(不需要 ...
- 洛谷P2617 Dynamic Rankings
带修主席树模板题 主席树的单点修改就是把前缀和(大概)的形式改成用树状数组维护,每个树状数组的元素都套了一个主席树(相当于每个数组的元素root[i]都是主席树,且这个主席树维护了(i - lowbi ...
- 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大
我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...
- 洛谷$P2617\ Dynamic\ Rankings$ 整体二分
正解:整体二分 解题报告: 传送门$w$ 阿查询带修区间第$k$小不显然整体二分板子呗,,, 就考虑先按时间戳排序(,,,其实并不需要读入的时候就按着时间戳排的鸭$QwQ$ 每次二分出$mid$先把所 ...
- 洛谷P2617 Dynamic Ranking(主席树,树套树,树状数组)
洛谷题目传送门 YCB巨佬对此题有详细的讲解.%YCB%请点这里 思路分析 不能套用静态主席树的方法了.因为的\(N\)个线段树相互纠缠,一旦改了一个点,整个主席树统统都要改一遍...... 话说我真 ...
- 洛谷 P2617 Dynamic Ranking
题目描述 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]……a[j]中第k小的数是多少(1≤k≤ ...
- P2617 Dynamic Rankings(树状数组套主席树)
P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...
随机推荐
- ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十四节--后台工作者HangFire与ABP框架Abp.Hangfire及扩展
返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 HangFire与Quartz.NET相比主要是HangFire的内置提供集成化的控制台,方便后台查看及监控,对于 ...
- jenkins中配置svn 出现absolute path is not allowed
代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 想用jenkins作自动化部署tomcat. svn代码已经checkout到本地目录了(/ ...
- 继承:call、apply、bind方法
javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. call,apply,bind这 ...
- D. Little C Loves 3 II
传送门 [http://codeforces.com/contest/1047/problem/D] 题意 给你n*m得棋盘,让你找两点之间距离为3的点的个数,不能重复使用,距离定义,两坐标差绝对值之 ...
- 开源RabbitMQ操作组件
开源RabbitMQ操作组件 对于目前大多的.NET项目,其实使用的技术栈都是差不多,估计现在很少用控件开发项目的了,毕竟一大堆问题.对.NET的项目,目前比较适合的架构ASP.NET MVC,ASP ...
- WIN10 评估版 查看过期时间
命令行运行winver,弹出的窗口显示过期时间,如 下图: 又可以再用一段时间教育版了,本机预装的的家庭版序列号,还没法从教育版降级到家庭版,可悲吧(win7时代就不允许从高级降低到低级用啊)
- jq源码解析之绑在$,jQuery上面的方法
1.当我们用$符号直接调用的方法.在jQuery内部是如何封装的呢?有没有好奇心? // jQuery.extend 的方法 是绑定在 $ 上面的. jQuery.extend( { //expand ...
- mysql复杂查询
所谓复杂查询,指涉及多个表.具有嵌套等复杂结构的查询.这里简要介绍典型的几种复杂查询格式. 一.连接查询 连接是区别关系与非关系系统的最重要的标志.通过连接运算符可以实现多个表查询.连接查询主要包括内 ...
- java中的随机数Random
java中一般有两种随机数,一个是Math中random()方法,一个是Random类. 一.Math.random() : 随即生成0<x<1的小数 实例:如何写,生成随机生成 ...
- [日常工作] cmd以及bash 直接使用当前目录的方法
1. 从知乎学到了一点.. 2. 之前想在比如f:\a\b 目录下执行cmd命令的时候 总是需要先 f: 再cd目录的方式. 3. 知乎上面学到 发现可以通过在当前目录下面 输入 cmd 或者是 b ...