所谓树状数组套权值线段树,就是在树状树组上套权值线段树

(逃)

解析

如何解决静态区间第k小?
使用主席树就ok啦

辣么如何解决动态区间第k小嘞…

我们想想主席树为啥不能解决动态区间第k小
因为如果改了一个点的值,后面所以的权值线段树都需要修改
单次修改的时空复杂度为nlognnlognnlogn,无法承受

仔细想想,静态的主席树似乎就是一个关于值域的高级一点的前缀和
暴力修改前缀和当然是需要修改O(n)O(n)O(n)个了
但是既然是前缀和,我们为就可以想到用树状数组优化
这样需要修改的东西就变成了O(logn)O(logn)O(logn)个了

具体的说,和树状数组的定义类似,第i棵权值线段树维护的是[i−lowbit(i)+1,i][i-lowbit(i)+1,i][i−lowbit(i)+1,i]的值域
这样单次修改只需要改log棵树
时空复杂度nlogn2nlogn^2nlogn2
询问的时候把对应的log棵树都拿出来
一起算size就可以了
时间复杂度nlogn2nlogn^2nlogn2
可以说是很优秀了
板子传送门

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+100;
inline ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;
}
int n,m;
int r[N],tot;
struct node{int ls,rs,siz;
}tr[N*300];
inline int New(){++tot;tr[tot].ls=tr[tot].rs=0;return tot;
}
#define mid ((l+r)>>1)
inline void pushup(int k){if(k) tr[k].siz=tr[tr[k].ls].siz+tr[tr[k].rs].siz;return;
}
inline void upd(int &k,int l,int r,int p,int v){if(!k) k=New();if(l==r){tr[k].siz+=v;return;}if(p<=mid) upd(tr[k].ls,l,mid,p,v);else upd(tr[k].rs,mid+1,r,p,v);pushup(k);//printf("  k=%d (%d %d),siz=%d\n",k,l,r,tr[k].siz);
}
int a[N],q[N],cnt;
inline void change(int p,int v){for(int i=p;i<=n;i+=i&-i){upd(r[i],1,cnt,a[p],-1);upd(r[i],1,cnt,v,1);}a[p]=v;return;
}
vector<int>L,R;
void get(int l,int rr){L.clear();R.clear();for(int i=l-1;i;i-=i&-i) L.push_back(r[i]);for(int i=rr;i;i-=i&-i) R.push_back(r[i]);return;
}
int ask(int l,int r,int k){if(l==r) return q[l];int num=0;for(int i=0;i<R.size();i++){int x=R[i];num+=tr[tr[x].ls].siz;}for(int i=0;i<L.size();i++){int x=L[i];num-=tr[tr[x].ls].siz;}if(k<=num){for(int i=0;i<R.size();i++){R[i]=tr[R[i]].ls;}for(int i=0;i<L.size();i++){L[i]=tr[L[i]].ls;}return ask(l,mid,k);}else{for(int i=0;i<R.size();i++){R[i]=tr[R[i]].rs;}for(int i=0;i<L.size();i++){L[i]=tr[L[i]].rs;}return ask(mid+1,r,k-num);}
}
char op[N];
int x[N],y[N],k[N];
int main(){n=read();m=read();for(int i=1;i<=n;i++){a[i]=read();q[++cnt]=a[i];}for(int i=1;i<=m;i++){scanf(" %c",&op[i]);x[i]=read();y[i]=read();if(op[i]=='Q') k[i]=read();else q[++cnt]=y[i];}sort(q+1,q+1+cnt);cnt=unique(q+1,q+1+cnt)-q-1;for(int i=1;i<=n;i++){//printf("\ni=%d\n",i);a[i]=lower_bound(q+1,q+1+cnt,a[i])-q;for(int p=i;p<=n;p+=p&-p){//printf("upd:%d\n",p);upd(r[p],1,cnt,a[i],1);}}//for(int i=1;i<=n;i++) printf("i=%d rot=%d siz=%d\n",i,r[i],tr[r[i]].siz);for(int i=1;i<=m;i++){if(op[i]=='Q'){get(x[i],y[i]);printf("%d\n",ask(1,cnt,k[i]));}else{y[i]=lower_bound(q+1,q+1+cnt,y[i])-q;change(x[i],y[i]);}}return 0;
}

动态区间第k小:树状数组套权值线段树相关推荐

  1. 树套树 ----- P1975 [国家集训队]排队(树状数组套权值线段树求动态逆序对)

    解题思路: 首先我们知道交换两个数a[l]和a[r]a[l]和a[r]a[l]和a[r]影响到的区间是[l+1,r−1][l+1,r-1][l+1,r−1] 对于a[l]a[l]a[l],我们要减去[ ...

  2. 树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大

    题目链接 题目大意: 给你一个数组aaa,aaa有两个操作 询问aaa中[l,r][l,r][l,r]区间里面第kkk小的数是哪个? 修改axa_xax​为yyy 解题思路: 首先我们知道权值线段树是 ...

  3. 【BZOJ3295】动态逆序对,CDQ分治/BIT套权值线段树

    传送门 思路: 用来练习cdq的题目 断断续续纠结了2天 因为loli一直在考试 最后莫名乱搞了一发就A了? 实际上是考虑每一次修改对答案的贡献,即位置在1~x-1且大于x的数以及位置在x+1~n且小 ...

  4. 数据结构:树套树-替罪羊树套权值线段树

    BZOJ3065 本题是在BZOJ上的处女A,实在不应该拿这样一道题来开头 平衡树套线段树应该是树套树问题里比较难的一种了,当然我记得还有一个替罪羊树套Trie树的题,我是不信自己能写出来的. 外层的 ...

  5. 牛客网 暑期ACM多校训练营(第一场)J.Different Integers-区间两侧不同数字的个数-离线树状数组 or 可持久化线段树(主席树)...

    J.Different Integers 题意就是给你l,r,问你在区间两侧的[1,l]和[r,n]中,不同数的个数. 两种思路: 1.将数组长度扩大两倍,for(int i=n+1;i<=2* ...

  6. 计蒜客 2020 蓝桥杯省赛 B 组模拟赛(五)E区间dp H 裴蜀 J dp A-J 权值线段树

    题目链接 因为要去笔试.所以只打了两个小时,有点求快,很多细节没写好就匆匆交,而且没有检查,打的有点菜 C-煎牛排 做法: 所有的面的个数sum=2*n   然后sum/(2*k)即可. ans=ma ...

  7. P3157 动态逆序对 ,树状数组套动态开点线段树

    题目 洛谷题目链接 题解 在求整体的逆序对的数量时,很好办,直接用树状数组处理即可,不过在这时,我们还需要处理出一个数组pa[]pa[]pa[],其中pa[i]pa[i]pa[i]代表在区间[1,i) ...

  8. BZOJ1146[CTSC2008]网络管理——出栈入栈序+树状数组套主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条 ...

  9. 权值线段树小结(hdu多校,普通平衡树,郁闷的出纳员)

    之前刷了一点主席树的题目,但是没有系统的做过权值线段树的题目.主席树是多根权值线段树的综合.权值线段树可以解决在总区间里求第k大的问题.在普通的线段树里,我们每一个节点维护的是权值大小.但是在权值线段 ...

最新文章

  1. C# 的快捷键汇总(一)
  2. 中文微博客的热门锐推用户榜
  3. Django 1.11 bootstrap样式文件无法加载问题解决
  4. AtCoder Grand Contest 015
  5. 必读干货 | 如何做好向上管理,分享我实践多年的完整方法论
  6. android自动关闭uvc相机服务,android 调用系统相机崩溃的解决方案
  7. 走进markdown
  8. 【深度学习】图像匹配Siamese网络实验记录
  9. 使用遗传算法解决N皇后问题
  10. PL/SQL(一)简介
  11. 优秀图片标注工具 推荐
  12. 男生如何找准自己的穿衣风格,提升衣着品味(转载:搜狐男人)
  13. 计算机学院网络安全学院,网络空间安全学院
  14. PS调整图片内存大小快捷键
  15. 安富莱C语言编码规范
  16. 【大众点评评论爬虫】一键获取大众点评完整评论工具批量爬取保存为excel数据
  17. 【sql查询与优化】2.给查询结果排序
  18. 使用MMD模型通过Kivicube平台制作WebAR与小程序AR
  19. 什么是计算机系统性能,什么系统性能好?电脑发烧友告诉你
  20. FLAC3D模拟:复杂模型的建立与导入

热门文章

  1. java 1.8 vm_HotSpot虚拟机在java 1.8中的新实现
  2. 川大计算机文化基础在线作业,川大1309《计算机文化基础0008》在线作业2答案.docx...
  3. 两向量点乘坐标运算_高三数学冲刺复习之向量小题的题型总结(含好用的补充公式)...
  4. java 最好 入门_C++和Java哪个比较好入门?初学者该如何选择?
  5. python转字符_python 字符转换
  6. leedcode05 找出缺失的观测数据(思路加详解)
  7. 7-15 QQ帐户的申请与登陆 (25 分)(map做法+思路分析)
  8. [数据结构]树、森林与二叉树之间的相互转换方法
  9. [剑指offer]面试题19:二叉树的镜像
  10. C++set容器-插入和删除