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 ...
随机推荐
- iOS 日历类(NSCalendar)
对于时间的操作在开发中很常见,但有时候我们需要获取到一年后的时间,或者一周后的时间.靠通过秒数计算是不行的.那就牵扯到另外一个日历类(NSCalendar).下面先简单看一下 NSDate let d ...
- 分别用js和jq实现百度全选反选效果
js实现过程 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- 《javascript高级程序设计》对象图
1.原型链图 2.作用域链图 3.继承
- 切换加上延迟加载js代码
切换加上延迟加载js代码 (function(){ var tit = $("#tab02 li"), con = $("#wrapmp>div"), c ...
- CV牛人牛事简介之一
CV牛人牛事简介之一 [论坛按] 发帖人转载自:http://doctorimage.cn/2013/01/01/cv-intro-niubility/#6481970-qzone-1-83120-8 ...
- jQuery中的一些正则匹配表达式
jQuery常用正则匹配表达式 落雨 //整数 "^-?[1-9]\\d*$", //正整数 "^[1-9]\\d*$", //负整数 intege2: &qu ...
- C语言预处理运算符
转自C语言预处理运算符 预处理还需要运算符?有没有搞错? ^_^, 没有搞错,预处理是有运算符,而且还不止一个: #(单井号) -- 字符串化运算符. ##(双井号 )-- 连接运算符 #@ ...
- explain 用法详解
explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: expla ...
- [译]GotW #6a: Const-Correctness, Part 1
const 和 mutable在C++存在已经很多年了,对于如今的这两个关键字你了解多少? Problem JG Question 1. 什么是“共享变量”? Guru Question 2. con ...
- URAL1244. Gentlemen(背包)
链接 以前做的题 VJ太水了 数组里面的数可能会小于0 当时没判断 #include <iostream> #include<cstdio> #include<cstri ...