题目大意:维护带修改区间 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. 身在上海的她,该不该继续"坚持"前端开发?

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 一 对于目前的IT行业,我实在不想她还没在这个行业中站稳脚跟就开始有 ...

  2. open-falcon ---客户机agent操作

    open-falcon的agent用于采集机器负载监控指标,比如cpu.idle.load.1min.disk.io.util等等,每隔60秒push给Transfer.agent与Transfer建 ...

  3. Linux系统下CPU使用(load average)梳理

    在平时的运维工作中,当一台服务器的性能出现问题时,通常会去看当前的CPU使用情况,尤其是看下CPU的负载情况(load average).对一般的系统来说,根据cpu数量去判断.比如有2颗cup的机器 ...

  4. 【CV】ICCV2015_Unsupervised Visual Representation Learning by Context Prediction

    Unsupervised Visual Representation Learning by Context Prediction Note here: it's a learning note on ...

  5. Scrum Meeting NO.10

    Scrum Meeting No.10 1.会议内容 2.任务清单 徐越 序号 近期的任务 进行中 已完成 1 "我"回答过的问题 -- 界面 √ 2 "问题" ...

  6. PAT 1057 数零壹

    https://pintia.cn/problem-sets/994805260223102976/problems/994805270914383872 给定一串长度不超过 10​5​​ 的字符串, ...

  7. PAT 1014 福尔摩斯的约会

    https://pintia.cn/problem-sets/994805260223102976/problems/994805308755394560 大侦探福尔摩斯接到一张奇怪的字条:“我们约会 ...

  8. PAT 1071 小赌怡情

    https://pintia.cn/problem-sets/994805260223102976/problems/994805264312549376 常言道“小赌怡情”.这是一个很简单的小游戏: ...

  9. Hot code replace (HCR)

    https://wiki.eclipse.org/FAQ_What_is_hot_code_replace%3F https://zhidao.baidu.com/question/195505558 ...

  10. vuex的数据交互

    methods:{ ...mapMutations({aaa:hs}) //将mutations的方法暴露出来,进行调用 aaa是他的名字 ...mapActions(['hs']) //将actio ...