带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的。。。

主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n*log n 的复杂度

现在介绍这种待修改的主席树,本质上是用树状数组的区间查询维护的线段树,树状数组的每个点,都开一个权值线段树,维护的是lowbit(x)-x之间的数字的出现次数

这样我们相当于,把一个1-n权值线段树,用树状数组给砍成logn段,这样就非常方便。。。我们用树状数组遍历维护前缀和的过程,变成维护树的前缀的过程,这样单次维护的复杂度,大概为两个log,还是可以接受的

模版题

#include<bits/stdc++.h>
using namespace std;
const int maxx = 2e5+;
struct node{
int l,r,cnt;
}tree[maxx*];
struct query{
int l,r,k;
}que[maxx*];
int trl[maxx],trr[maxx],a[maxx],root[maxx];
int cnt,lenx,leny,n,sz;
vector<int>p;
void update(int l,int r,int pre,int &now,int pos,int w){
now=++cnt;
tree[now]=tree[pre];
tree[now].cnt+=w;
if (l==r)
return ;
int mid=(l+r)>>;
if (pos<=mid){
update(l,mid,tree[pre].l,tree[now].l,pos,w);
}else{
update(mid+,r,tree[pre].r,tree[now].r,pos,w);
}
}
/**查询区间第k大**/
int query(int l,int r,int k){
if(l==r)
return l;
int s=;
///查询区间个数
for (int i=;i<=lenx;i++){
s-=tree[tree[trl[i]].l].cnt;
}
for (int i=;i<=leny;i++){
s+=tree[tree[trr[i]].l].cnt;
}
int mid=(l+r)>>;
if(k<=s){
///把询问变成询问单点的左子树
for(int i=;i<=lenx;i++){
trl[i]=tree[trl[i]].l;
}
for(int i=;i<=leny;i++){
trr[i]=tree[trr[i]].l;
}
return query(l,mid,k);
}else {
///把询问变成询问单点的右子树
for(int i=;i<=lenx;i++){
trl[i]=tree[trl[i]].r;
}
for(int i=;i<=leny;i++){
trr[i]=tree[trr[i]].r;
}
return query(mid+,r,k-s);
}
}
int lowbit(int x){
return x&(-x);
}
void add(int x,int w){
int pos=lower_bound(p.begin(),p.end(),a[x])-p.begin()+;
for (int i=x;i<=n;i+=lowbit(i)){
update(,sz,root[i],root[i],pos,w);
}
}
int main(){
int q;
scanf("%d%d",&n,&q);
cnt=;
for (int i=;i<=n;i++){
scanf("%d",&a[i]);
p.push_back(a[i]);
}
for (int i=;i<=q;i++){
char op[];
scanf("%s",op);
if(op[]=='C'){
scanf("%d%d",&que[i].l,&que[i].r);
que[i].k=;
p.push_back(que[i].r);
}else{
scanf("%d%d%d",&que[i].l,&que[i].r,&que[i].k);
}
}
///把点全部离散排序
sort(p.begin(),p.end());
p.erase(unique(p.begin(),p.end()),p.end());
sz=p.size();
for (int i=;i<=n;i++){
add(i,);
}
for (int i=;i<=q;i++){
if (que[i].k){
lenx=;leny=;
for (int j=que[i].r;j;j-=lowbit(j)){
trr[++leny]=root[j];
}
for (int j=que[i].l-;j;j-=lowbit(j)){
trl[++lenx]=root[j];
}
printf("%d\n",p[query(,sz,que[i].k)-]);
}else{
///前缀中删除这个树的影响
add(que[i].l,-);
a[que[i].l]=que[i].r;
add(que[i].l,);
}
}
return ;
}

[luogu P2617] Dynamic Rankings 带修主席树的更多相关文章

  1. BZOJ1901 Dynamic Rankings|带修主席树

    题目链接:戳我 其实我并不会做,于是看了题解 我们都知道主席树是利用前缀和记录历史版本来搞区间K大的一种数据结构.不过一般的主席树只能搞定静态区间第K大.如果带修怎么办呢? 想一下...单点修改+区间 ...

  2. 【BZOJ-1901】Dynamic Rankings 带修主席树

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7292  Solved: 3038[Su ...

  3. BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树

    题目: emmmm是个权限题 题解: 带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改 修改的时候修改类似树状数组一样进行logn个Insert 查询的时候同理,树状数组的方法 ...

  4. P2617 Dynamic Rankings(带修主席树)

    所谓带修主席树,就是用树状数组的方法维护主席树的前缀和 思路 带修主席树的板子 注意数据范围显然要离散化即可 代码 #include <cstdio> #include <cstri ...

  5. 【BZOJ-1146】网络管理Network DFS序 + 带修主席树

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3495  Solved: 1032[Submi ...

  6. Luogu P2617 Dynamic Rankings

    带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了. 核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然 ...

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

  8. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

    3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...

  9. luogu P2617 Dynamic Rankings(主席树)

    嘟嘟嘟 一句话题意:带修改区间第\(k\)小. 不修改都会,主席树板子.但是有修改就要比较深入的理解主席树了. 众所周知,主席树中以\(i\)为根的线段树维护的是\([1, i]\)这个前缀的权值,因 ...

随机推荐

  1. solr高亮及摘要

    修改了原文的一点内容:原文地址为:http://www.cnblogs.com/rainbowzc/p/3680343.html 高亮显示 两种方法: 1.在程序里通过设置query返回高亮信息 pu ...

  2. Angungular.js 的过滤器&工具方法

    字母大小写 数字 货币 截取字符串 截取数组 用JS操作 ----------------------------------------------------------------------- ...

  3. mvp例子与MVVM例子

    VMP例子 <!-- 从百度CDN上面找个jquery的链接 --> <!DOCTYPE html> <html lang="en"> < ...

  4. activity与fragment之间的传递数据

    首先activity之间的数据传递就是 用intent和intent+bundle intent 传递 Intent i= new Intent(MainActivity.this,TheAty.cl ...

  5. WPF ScrollViewer嵌套Listbox无法滚动

    最近在做项目的时候,发现listBoxzi自带的垂直滚动条有问题,经常在Add(item)的时候下面会多出一些空白的部分,而且滚动条的长度也是无规则的,一会大一会小,而且无法控制横竖滚动条的显隐藏,并 ...

  6. Ubuntu查找通过apt命令已安装软件

    方法一 apt list --installed 方法二 dpkg -l

  7. Codeforces 442C

    题目链接 C. Artem and Array time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  8. 【JZOJ4899】【NOIP2016提高A组集训第17场11.16】雪之国度

    题目描述 雪之国度有N座城市,依次编号为1到N,又有M条道路连接了其中的城市,每一条道路都连接了不同的2个城市,任何两座不同的城市之间可能不止一条道路.雪之女王赋予了每一座城市不同的能量,其中第i座城 ...

  9. Neo4j学习笔记(1)——使用Java API实现简单的增删改查

    阅读目录 项目的创建及配置 使用嵌入式数据库 创建节点和关系 查询及更新 删除关系和节点 完整代码 参考资料 回到顶部 项目的创建及配置 因为Neo4j依赖的jar包比较多,所以推荐使用Maven来管 ...

  10. 手机monkey测试BUG重现及解决方法

    目录 1.1 Monkey测试简介...1 1.2 Monkey程序介绍...1 1.3 Monkey命令的简单帮助...2 1.4 Monkey命令参数介绍...2 1.5 Monkey测试步骤.. ...