题目链接

  树状数组套主席树有点难懂qwq  不好理解

  树状数组套主席树的直观理解应该是:树状数组的每一个节点是一棵主席树。

  普通区间修改我们是创建1个线段树,树状数组套主席树的时候我们就创建log个线段树。

  普通区间查询我们是把from-1 和to 两个线段树作差,树状数组套主席树的时候我们就把from-1的前缀和的log个线段树和to的log个线段树作差。

  比较玄学qwq   我好像现在还是没懂

  放上代码吧

  

#include<cctype>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#define mid ((l+r)>>1)
#define maxn 10005 using namespace std; inline long long read(){
long long num=,f=;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') f=-;
ch=getchar();
}
while(isdigit(ch)){
num=num*+ch-'';
ch=getchar();
}
return num*f;
} inline int low(int i){ return i&(-i); } int s[maxn*],q[maxn*];
int rt[maxn**];
int sum[maxn**];
int ls[maxn**];
int rs[maxn**];
int d[maxn],w[maxn],tot,n,m,size,point,totd,totw; void build(int &o,int l,int r){
o=++tot;
if(l==r) return;
build(ls[o],l,mid);
build(rs[o],mid+,r);
} void update(int &o,int l,int r,int last,int p,int val){
o=++tot; ls[o]=ls[last]; rs[o]=rs[last]; sum[o]=sum[last]+val;
if(l==r) return;
if(p<=mid) update(ls[o],l,mid,ls[last],p,val);
else update(rs[o],mid+,r,rs[last],p,val);
} void add(int from,int val){
int value=q[from];
while(from<=n){
update(rt[from],,size,rt[from],value,val);
from+=low(from);
}
} int query(int l,int r,int e){
if(l==r) return l;
int cnt=;
for(int i=;i<=totw;++i) cnt+=sum[ls[w[i]]];
for(int i=;i<=totd;++i) cnt-=sum[ls[d[i]]];
if(e<=cnt){
for(int i=;i<=totd;++i) d[i]=ls[d[i]];
for(int i=;i<=totw;++i) w[i]=ls[w[i]];
return query(l,mid,e);
}
else{
for(int i=;i<=totd;++i) d[i]=rs[d[i]];
for(int i=;i<=totw;++i) w[i]=rs[w[i]];
return query(mid+,r,e-cnt);
}
} struct Que{
bool f;
int from,to,rank;
void add(int opt,int x,int y,int z){
f=opt;from=x;to=y;rank=z;
}
}que[maxn]; int main(){
n=read(),m=read();
for(int i=;i<=n;++i) s[++point]=q[i]=read();
for(int i=;i<=m;++i){
char ch[];int x,y;
scanf("%s%d%d",ch,&x,&y);
if(ch[]=='Q'){
int z=read();
que[i].add(,x,y,z);
}
else{
que[i].add(,x,y,);
s[++point]=y;
}
}
sort(s+,s+point+);
size=unique(s+,s+point+)-s-;
for(int i=;i<=n;++i) q[i]=lower_bound(s+,s+size+,q[i])-s;
for(int i=;i<=m;++i)
if(que[i].f) que[i].to=lower_bound(s+,s+size+,que[i].to)-s;
//build(rt[0],1,size);
for(int i=;i<=n;++i) add(i,);
for(int i=;i<=m;++i){
bool f=que[i].f;int from=que[i].from,to=que[i].to,rank=que[i].rank;
if(f){
add(from,-); q[from]=to; add(from,);
}
else{
totd=totw=;
for(int j=from-;j;j-=low(j)) d[++totd]=rt[j];
for(int j=to;j;j-=low(j)) w[++totw]=rt[j];
printf("%d\n",s[query(,size,rank)]);
}
}
return ;
}

【Luogu】P2617Dynamic Ranking(树状数组套主席树)的更多相关文章

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

    传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...

  2. BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

    [题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...

  3. BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树

    [题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...

  4. BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树

    BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...

  5. ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解

    题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...

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

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

  7. [COGS257]动态排名系统 树状数组套主席树

    257. 动态排名系统 时间限制:5 s   内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...

  8. BZOJ 2141 排队(树状数组套主席树)

    解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...

  9. 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】

    题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...

随机推荐

  1. 2017“编程之美”终章:AI之战勇者为王

    编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...

  2. 基于BranchTraceStore机制的CPU执行分支追踪工具 —— CpuWhere [修正版 仅驱动]

    [前言] 在张银奎老师的<软件调试>一书中,详细地讲解了使用内存的分支记录机制——BTS机制(5.3),并且给出了示例工具CpuWhere及其源代码.但实际运行(VMware XP_SP3 ...

  3. sparkmlib-相关系数

    一.基本原理 在stat包中实现了皮尔逊(Pearson)与 斯皮尔曼(Spearman)两类相关系数的计算 (1)Pearson:   (x,y)协方差/[(x标准方差)*(y标准方差)] 详情可以 ...

  4. 92.背包问题(lintcode)

    注意j-A[i-1]必须大于等于0,只大于0会报错 class Solution { public: /** * @param m: An integer m denotes the size of ...

  5. Hibernate中get()与load()的区别,以及关于ThreadLocal的使用方法

    一.get方法和load方法的简易理解 (1)get()方法直接返回实体类,如果查不到数据则返回null.load()会返回一个实体代理对象(当前这个对象可以自动转化为实体对象),但当代理对象被调用时 ...

  6. java数字金额转化为中文金额

    public static String digitUppercase(double n){String fraction[] = {"角", "分"};Str ...

  7. glassfish配置中数据库密码加密方法

    glassfish配置中数据库密码加密方法 Glassfish中的数据库连接池需要使用密文保存数据库密码.如果不是,则可按如下方法可配置 通过Glassfish中的Alias实现,配置方法如下: 1. ...

  8. ios之coredata(二)

    上面一篇文章介绍了coredata的有关基本概念,由于大部分是参考别人文章中的内容,所以感觉有点虚,而且估计也是比较难以理解,下面这篇文章通俗一点说说学习coredata后的一些理解,然后给出一个简单 ...

  9. shell基础笔记1

    ---恢复内容开始--- 1 test命令中不能使用浮点小数值,如:    A=1.444444:[    $A -gt 1  ] 2 test命令中的>或<必须转义,否则shell会把它 ...

  10. jQuery实现滚动条下拉时无限加载

    var lastId=0;//记录每一次加载时的最后一条记录id,跟您的排序方式有关. var isloading = false; $(window).bind("scroll" ...