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

主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到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. Linux 中查询 CPU 的核数的方法

    以一台 Linux 服务器为例.这台 Linux 包括两颗 Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz CPU, 单颗 CPU 包括 10 个 cpu core ...

  2. mysql导入数据中文乱码解决方法

    常见的MySQL导入方法有两种 第一种方法,使用MySQL命令导入 mysql -uroot -p123456 --default-character-set=utf8 [db_name] < ...

  3. update当根据条件不同时 更新同一个字段的方法 或多表插入

    1.通过存储过程 循环 传值 create or replace procedure p_u isbegin for rs in (select distinct (rks) from rkbz)lo ...

  4. Oracle中Function学习2

    上一节说函数 这回聊一下 存储过程:有了上节知识点,对这个也许会一种小感觉.呵呵 过程(存储过程):与过程相比, 存储过程是存在数据库中的一个对象 我主要通过例子来了解 不做多解释 相信你也能明白: ...

  5. Mysql 5.7.17安装后登录mysql的教程方法

    在运行 ./bin/mysqld Cinitialize 初始化数据库时,会生成随机密码,示例: [Note] A temporary password is generated for root@l ...

  6. LUGOU P3907 圈的异或

    传送门 解题思路 其实就是找出所有的环判断,因为数据范围很小直接暴力做,注意要判断自环. 代码 #include<iostream> #include<cstdio> #inc ...

  7. vue制作幻灯片-左右移动

    组件中: <template> <div class="slide-show" @mouseover="clearInv" @mouseout ...

  8. php实现图片以base64显示的方法达到效果

    目前Data URI scheme支持的类型有: data:text/plain,文本数据data:text/html,HTML代码data:text/html;base64,base64编码的HTM ...

  9. nodeJs学习-16 数据字典示例

    1.banner ID title 标题 varchar(32) sub_title 副标题 varchar(16) src 图片地址 varchar(64) 2.文章 ID author 作者 va ...

  10. MYSQL中LIMIT用法_后台分页

    LIMIT是MySQL内置函数,其作用是用于限制查询结果的条数. 1)其语法格式如下: LIMIT[位置偏移量,]行数 其中,中括号里面的参数是可选参数,位置偏移量是指MySQL查询分析器要从哪一行开 ...