题目大意

给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下:

Q l r k 要求你查询区间[l,r]第k小的数是哪个

C i t  要求你把第i个数修改为t

题解

动态的区间第k小,如果还是按照静态的主席树做的话,每次修改需要对n个线段树进行修改,这样显然会TLE,所以我们需要用树状数组,这样每次只需要对logn颗线段树修改即可,修改的时间复杂度为logn^2,询问的时间复杂度为logn^2,空间复杂度为nlogn^2

还有一种空间复杂度为nlogn+mlogn^2的方法,就是先建立n颗静态的主席树,空间复杂度为nlogn,然后再更新的时候用树状数组套线段树,这样空间复杂度为mlogn^2,所以总空间复杂度为nlogn+mlogn^2

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 140000
#define NN 10005
#define lson l,m,ls[s]
#define rson m+1,r,rs[s]
int ls[*MAXN],rs[*MAXN],cnt[*MAXN];
int T[MAXN],tot;
int len,n,m;
int num[MAXN];
char op[][];
int a[NN*],lt[NN],rt[NN],K[NN];
int L[],R[];
int N,M;
void build(int l,int r,int &s)
{
s=++tot;
cnt[s]=;
if(l==r) return;
int m=(l+r)>>;
build(lson);
build(rson);
}
void update(int last,int p,int l,int r,int &s,int d)
{
s=++tot;
ls[s]=ls[last],rs[s]=rs[last],cnt[s]=cnt[last]+d;
if(l==r) return;
int m=(l+r)>>;
if(p<=m) update(ls[last],p,lson,d);
else update(rs[last],p,rson,d); }
int query(int l,int r,int k)
{
if(l==r) return r;
int suma=,sumb=;
for(int i=; i<=N; i++) suma+=cnt[ls[L[i]]];
for(int i=; i<=M; i++) sumb+=cnt[ls[R[i]]];
int m=(l+r)>>,sum=sumb-suma;
if(sum>=k)
{
for(int i=; i<=N; i++) L[i]=ls[L[i]];
for(int i=; i<=M; i++) R[i]=ls[R[i]];
return query(l,m,k);
}
else
{
for(int i=; i<=N; i++) L[i]=rs[L[i]];
for(int i=; i<=M; i++) R[i]=rs[R[i]];
return query(m+,r,k-sum);
}
}
int lowbit(int x)
{
return x&-x;
}
void BIT(int x,int value,int d)
{
while(x<=n)
{
update(T[x],value,,len,T[x],d);
x+=lowbit(x);
}
}
int BIT_query(int l,int r,int k)
{
N=,M=;
while(l>)
{
L[++N]=T[l];
l-=lowbit(l);
}
while(r>)
{
R[++M]=T[r];
r-=lowbit(r);
}
return query(,len,k);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
{
scanf("%d",&num[i]);
a[++len]=num[i];
}
for(int i=; i<=m; i++)
{
scanf("%s%d%d",op[i],&lt[i],&rt[i]);
if(op[i][]=='Q') scanf("%d",&K[i]);
else
a[++len]=rt[i];
}
sort(a+,a+len+);
len=unique(a+,a+len+)-a-;
for(int i=; i<=n; i++) num[i]=lower_bound(a+,a++len,num[i])-a;
build(,len,T[]);
for(int i=; i<=n; i++) BIT(i,num[i],);
for(int i=; i<=m; i++)
if(op[i][]=='Q')
printf("%d\n",a[BIT_query(lt[i]-,rt[i],K[i])]);
else
{
BIT(lt[i],num[lt[i]],-);
int pos=lower_bound(a+,a+len+,rt[i])-a;
num[lt[i]]=pos;
BIT(lt[i],pos,);
}
return ;
}

BZOJ1901 - Dynamic Rankings(树状数组套主席树)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

  10. Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)

    E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...

随机推荐

  1. Pjax介绍及在asp.net MVC3中使用pjax的简单示例

    相信很多人对ajax并不陌生,对ajax的一些优点也了如指掌,如:局部刷新改善用户体验,减少开销,让服务器和浏览器之间的响应更快等. 但是它的缺点也是很显而易见的: AJAX大量的使用了javascr ...

  2. hdu 4542 小明系列故事——未知剩余系

    小明系列故事——未知剩余系 题意:操作0表示某数有n个约数,操作1为某数有n个非约数:n <= 47777,若是存在小于2^62的数符合,则输出该数,否则若是不存在输出Illegal,若是大于2 ...

  3. HDFS文件读写流程 (转)

    文件读取的过程如下: 使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求: Namenode会视情况返回文件的部分或者全部block列表,对于每个block,Namen ...

  4. 25个App免费资源网站

    不少非常优秀的设计师已经在网络分享了很多出色的图标.界面 PSD 文件,再加上其他一些相关资源,设计 iOS 应用更加方便了. 模板 & PSDs  Icon Template Michael ...

  5. 解决WP8应用里ListBox绑定数据变多导致越来越卡

    ListBox控件绑定数据,当滑动到底部的时候加载数据到列表上,这样就会产生一个问题,当ListBox上面绑定的数据有几千条的时候,界面将会卡顿,我们可以通过在ListBox上只绑定指定数量的数据,其 ...

  6. uva 165 Stamps

    题意: 现有k种邮票面额, 一封信上最多贴h张邮票. 求能贴出的最大连续区间,即[1, max_value]这个区间内的所有面额都能贴出来. 并输出k种面额, h + k <= 9. 思路: 这 ...

  7. Compass 使用手册

    在EDM中使用基准   定义和基准相关的术语     这一段定义了基准术语.可以在属性对话框中知道   项目属性           系统基准         系统基准在项目属性里设置,并且值为0.它 ...

  8. 【深度学习系列2】Mariana DNN多GPU数据并行框架

    [深度学习系列2]Mariana DNN多GPU数据并行框架  本文是腾讯深度学习系列文章的第二篇,聚焦于腾讯深度学习平台Mariana中深度神经网络DNN的多GPU数据并行框架.   深度神经网络( ...

  9. Codeforces Round #208 (Div. 2)

    A - Dima and Continuous Line 水题:直接模拟: #include<cstdio> #define maxn 1005 using namespace std; ...

  10. 查看linux系统的版本

    1. 查看内核版本命令: 1) [root@SOR_SYS ~]# cat /proc/version Linux version 2.6.18-238.el5 (mockbuild@x86-012. ...