BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意
给定一个有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],<[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(树状数组套主席树)的更多相关文章
- P2617 Dynamic Rankings(树状数组套主席树)
P2617 Dynamic Rankings 单点修改,区间查询第k大 当然是无脑树套树了~ 树状数组套主席树就好辣 #include<iostream> #include<cstd ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- ZOJ 2112 Dynamic Rankings(树状数组套主席树 可修改区间第k小)题解
题意:求区间第k小,节点可修改 思路:如果直接用静态第k小去做,显然我更改一个节点后,后面的树都要改,这个复杂度太高.那么我们想到树状数组思路,树状数组是求前缀和,那么我们可以用树状数组套主席树,求出 ...
- LUOGU P2617 Dynamic Rankings(树状数组套主席树)
传送门 解题思路 动态区间第\(k\)大,树状数组套主席树模板.树状数组的每个位置的意思的是每棵主席树的根,维护的是一个前缀和.然后询问的时候\(log\)个点一起做前缀和,一起移动.时空复杂度\(O ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树
BZOJ_3196_Tyvj 1730 二逼平衡树_树状数组套主席树 Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排 ...
- [COGS257]动态排名系统 树状数组套主席树
257. 动态排名系统 时间限制:5 s 内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[ ...
- BZOJ 2141 排队(树状数组套主席树)
解法很多的题,可以块套树状数组,可以线段树套平衡树.我用的是树状数组套主席树. 题意:给出一段数列,m次操作,每次操作是交换两个位置的数,求每次操作后的逆序对数.(n,m<=2e4). 对于没有 ...
- 洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】
题目链接 洛谷P3759 题解 树状数组套主席树板题 #include<algorithm> #include<iostream> #include<cstring> ...
- 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 ...
随机推荐
- 如何让VS2012同时调试2个项目
- hdu 2222 Keywords Search ac自动机入门
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222 题意:有N(N <= 10000)个长度不超过50的模式串和一个长度不超过1e6的文本串. ...
- ubuntu系统软件
1.办公软件:wps 2.浏览器:firefox,opera 3.思维导图:xmind 如果您有好的软件,请推荐给我,谢谢!
- ColorDialog组件设置字体颜色
1.设置颜色 private void button4_Click(object sender, EventArgs e) { this.colorDialog1.ShowDialog(); this ...
- qt 5 界面美化
大家都知道,用UI做起界面来非常方便,但是如果我们不熟练他的操作的话,做起来也会有不少布局的麻烦, 所以,我打算写一篇文章来记录自己参考大牛用代码写界面的文章,感谢百度,感谢各位QT大牛的帮助. 所谓 ...
- 认识基本的UI资源
什么是UI精灵(Sprite) 在制作UI时,经常将一些零碎的小的UI资源(比如,一个小箭头,一个按钮等)打包成一张大图,然后在使用时,只使用这个大图中的一部分,那么这一块"被切出来&quo ...
- Javascript 5种方法实现过滤删除前后所有空格
第一种:循环检查替换 //供使用者调用 function trim(s){ return trimRight(trimLeft(s)); } //去掉左边的空白 function trimLeft(s ...
- windows store app promise
Promise.any ---- 参数是一个promise的数组.any的作用就是 promise 数组中任意一个 promise 执行完毕,就会执行 done内的函数 (function () { ...
- 设置html滚动条(陶庭飞问题)
var height = document.body.scrollHeight; parent.document.all("rightFrame").style.height = ...
- hdu 1255 覆盖的面积 (线段树处理面积覆盖问题(模板))
http://acm.hdu.edu.cn/showproblem.php?pid=1255 覆盖的面积 Time Limit: 10000/5000 MS (Java/Others) Memo ...