题目大意:维护带修改区间 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的更多相关文章

  1. 洛谷P2617 Dynamic Rankings (主席树)

    洛谷P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a ...

  2. 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 ...

  3. 洛谷 P2617 Dynamic Rankings 解题报告

    P2617 Dynamic Rankings 题目描述 给定一个含有\(n\)个数的序列\(a[1],a[2],a[3],\dots,a[n]\),程序必须回答这样的询问:对于给定的\(i,j,k\) ...

  4. 洛谷 P2617 Dynamic Rankings || ZOJ - 2112

    写的让人看不懂,仅留作笔记 静态主席树,相当于前缀和套(可持久化方法构建的)值域线段树. 建树方法:记录前缀和的各位置的线段树的root.先建一个"第0棵线段树",是完整的(不需要 ...

  5. 洛谷P2617 Dynamic Rankings

    带修主席树模板题 主席树的单点修改就是把前缀和(大概)的形式改成用树状数组维护,每个树状数组的元素都套了一个主席树(相当于每个数组的元素root[i]都是主席树,且这个主席树维护了(i - lowbi ...

  6. 洛谷P2617 Dynamic Rankings 主席树 单点修改 区间查询第 K 大

    我们将线段树套在树状数组上,查询前预处理出所有要一起移动的节点编号,并在查询过程中一起将这些节点移到左右子树上. Code: #include<cstdio> #include<cs ...

  7. 洛谷$P2617\ Dynamic\ Rankings$ 整体二分

    正解:整体二分 解题报告: 传送门$w$ 阿查询带修区间第$k$小不显然整体二分板子呗,,, 就考虑先按时间戳排序(,,,其实并不需要读入的时候就按着时间戳排的鸭$QwQ$ 每次二分出$mid$先把所 ...

  8. 洛谷P2617 Dynamic Ranking(主席树,树套树,树状数组)

    洛谷题目传送门 YCB巨佬对此题有详细的讲解.%YCB%请点这里 思路分析 不能套用静态主席树的方法了.因为的\(N\)个线段树相互纠缠,一旦改了一个点,整个主席树统统都要改一遍...... 话说我真 ...

  9. 洛谷 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≤ ...

  10. P2617 Dynamic Rankings(树状数组套主席树)

    P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...

随机推荐

  1. javascript调用ActiveX接口失败的解决方案及使用心得

    前段时间公司做了个比较大的项目,需要用到ocx控件,我厂大部分项目都采用C#.net,而winform程序条用ocx控件接口是相对简单的,但是javascript调用ocx接口,却和winform的用 ...

  2. Log4net_简单使用

    log4net 有四种主要的组件,分别是Logger(记录器), Repository(库), Appender(附着器)以及 Layout(布局). 第一步:Log4net的安装 Install-P ...

  3. 【CV】ICCV2015_Unsupervised Learning of Visual Representations using Videos

    Unsupervised Learning of Visual Representations using Videos Note here: it's a learning note on Prof ...

  4. Linux课题实践一

    Linux课题实践一 20135318 刘浩晨 1.1应用安装 (1)掌握软件源的维护方法,配置系统使用软件源镜像  删除过期或者重复的软件包:进入”系统设置“-”软件和更新”-”ubuntu软件“- ...

  5. 数学建模-lingo使用

    1.安装启动,软件下载地址:http://pc.xzstatic.com/2017/06/LINGO14 .zip.此为免安装版,打开后双击Lingo11.exe即可启动软件. 2.示例:某商品单位成 ...

  6. hover设定触发时间间隔

    500毫秒执行一次 $(".banner_menu_content li a").hover(function(){ var aa=$(this).text().trim(); s ...

  7. 09-java学习-数组-冒泡排序-选择排序-数组工具类编写-查找-扩容

    数组的排序算法 查找算法 数组协助类Arrays的学习和使用 数组的扩容

  8. A Survey of Machine Learning Techniques Applied to Software Defined Networking (SDN): Research Issues and Challenges

    将机器学习用到SDN中的综述:研究的问题和挑战 从流量分类.路由优化.服务质量(Qos)/体验质量(QoE)预测.资源管理和安全性的角度,回顾了机器学习算法如何应用于SDN领域. 相关知识 在SDN中 ...

  9. Docker for windows 入门一(下载安装)

    预安装条件,可以查阅官方文档,本人是Win10 x64(必要条件)教育版+开启Hyper-V(Feature特性),具体可参考云栖社区的文章: https://yq.aliyun.com/articl ...

  10. laravel 数据库获取值的常用方法

    ---恢复内容开始--- find($id) 需要一个主键$id并返回一个模型对象,若不存在则返回null findOrFail($id) 需要一个主键$id并返回一个模型对象,若不存在则发生错误,抛 ...