BZOJ1901:Zju2112 Dynamic Rankings——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1901
Description
Input
Output
对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。
Sample Input
3 2 1 4 7
Q 1 4 3
C 2 6
Q 2 5 3
Sample Output
3
6
————————————————————————————
UPT:18.4.2美化代码,删改题解。
带修改主席树板子题目(bzoj真喜欢权限板子题)
然后我学了一上午:https://www.cnblogs.com/candy99/p/6166467.html
总的来说如果我们暴力修改主席树的话,我们对于每一棵主席树都需要进行修改,那么这样时间复杂度就爆棚了。
而我们考虑,树状数组和线段树的修改仅仅只是logn的。
所以我们试着让树状数组套上主席树,这样就能方便的修改值了。
也就是说,树状数组的每一个节点都挂着一棵主席树,这样所需要修改的主席树就变成O(logn)棵了。
那么查询也很简单,就是树状数组的查询方法(因为我们外层包的是树状数组,所以查询就是在查主席树的根,也就不需要主席树了)。
显然空间复杂度为O(nlognlogn)
!但是!我学的那篇博客提供了一种O(2nlogn)的做法。
我们直接将修改操作另开一棵树状数组(upt:其实是开一个主席树然后用树状数组的lowbit修改)维护,这样就变成了两个主席树了,查询的时候两者的和一加即可。
注意事项:
1.注意区分两个主席树,本代码中rt为原序列主席树,root为存修改的主席树。
2.空间记得根据空间复杂度开。
3.不要用什么玄学的stl,不然AC变TLE就是一瞬间的事情。
4.离散化。
#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N=;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct tree{
int l,r,sum;
}tr[N*];
struct question{
char s[];
int i,j,k,t;
}q[N];
int a[N],b[N],rt[N],root[N],n,m,Q,pool;
int q1[N],t1,q2[N],t2;
inline void initLSH(){
sort(b+,b+m+);
m=unique(b+,b+m+)-b-;
return;
}
inline int LSH(int v){return lower_bound(b+,b+m+,v)-b;}
inline int lowbit(int x){return x&-x;}
inline void insert(int y,int &x,int l,int r,int p,int v){
tr[x=++pool]=tr[y];
tr[x].sum+=v;
if(l==r)return;
int mid=(l+r)>>;
if(p<=mid)insert(tr[y].l,tr[x].l,l,mid,p,v);
else insert(tr[y].r,tr[x].r,mid+,r,p,v);
}
inline void add(int pos,int v){
int p=LSH(a[pos]);
for(int i=pos;i<=n;i+=lowbit(i))insert(root[i],root[i],,m,p,v);
//注意这里是root
}
inline int cal(){
int sum1=,sum2=;
for(int i=;i<=t1;i++)sum1+=tr[tr[q1[i]].l].sum;
for(int i=;i<=t2;i++)sum2+=tr[tr[q2[i]].l].sum;
return sum2-sum1;
}
inline int query(int nl,int nr,int k){
int l=,r=m;t1=t2=;
for(int i=nl;i;i-=lowbit(i))q1[++t1]=root[i];
for(int i=nr;i;i-=lowbit(i))q2[++t2]=root[i];
//注意这里是root
nl=rt[nl],nr=rt[nr];
//注意这里是rt
while(l<r){
int ls=cal()+tr[tr[nr].l].sum-tr[tr[nl].l].sum;
int mid=(l+r)>>;
if(k<=ls){
for(int i=;i<=t1;i++)q1[i]=tr[q1[i]].l;
for(int i=;i<=t2;i++)q2[i]=tr[q2[i]].l;
nl=tr[nl].l;nr=tr[nr].l;
r=mid;
}else{
for(int i=;i<=t1;i++)q1[i]=tr[q1[i]].r;
for(int i=;i<=t2;i++)q2[i]=tr[q2[i]].r;
nl=tr[nl].r;nr=tr[nr].r;
l=mid+;k-=ls;
}
}
return l;
}
int main(){
n=read();
Q=read();
for(int i=;i<=n;i++)a[i]=b[++m]=read();
for(int i=;i<=Q;i++){
scanf("%s",q[i].s);
if(q[i].s[]=='Q'){
q[i].i=read();q[i].j=read();q[i].k=read();
}
else{
q[i].i=read();
q[i].t=b[++m]=read();
}
}
initLSH();
for(int i=;i<=n;i++)insert(rt[i-],rt[i],,m,LSH(a[i]),);
//注意这里是rt
for(int i=;i<=Q;i++){
if(q[i].s[]=='Q')
printf("%d\n",b[query(q[i].i-,q[i].j,q[i].k)]);
else{
add(q[i].i,-);
a[q[i].i]=q[i].t;
add(q[i].i,);
}
}
return ;
}
BZOJ1901:Zju2112 Dynamic Rankings——题解的更多相关文章
- [BZOJ1901]Zju2112 Dynamic Rankings
[BZOJ1901]Zju2112 Dynamic Rankings 试题描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i ...
- BZOJ-1901 Zju2112 Dynamic Rankings 函数式线段树 套 树状数组+离线处理
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MB Submit: 6058 Solved: 2521 [Su ...
- BZOJ1901 Zju2112 Dynamic Rankings 主席树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1901 题意概括 给你一段序列(n个数),让你支持一些操作(共m次), 有两种操作,一种是询问区间第 ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- BZOJ1901 Zju2112 Dynamic Rankings 【树状数组套主席树】
题目 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i+2]--a[j]中第k小的数是多少(1≤k≤j- ...
- BZOJ1901——Zju2112 Dynamic Rankings
1.题目大意:区间第k小,有单点修改 2.分析:这个是树状数组套线段树,也是主席树....为什么主席树这么多QAQ 就是树套树的那种插入什么的,注意啊,一定要动态开内存..不然会爆.. 然后算答案有两 ...
- [luogu2617][bzoj1901][Zju2112]Dynamic Rankings【树套树+树状数组+主席树】
题目网址 [传送门] 题目大意 请你设计一个数据结构,支持单点修改,区间查询排名k. 感想(以下省略脏话inf个字) 真的强力吹爆洛谷数据,一般的树套树还给我T了一般的点,加强的待修主席树还给我卡了几 ...
- bzoj1901: Zju2112 Dynamic Rankings(BIT套主席树)
带修改的题主席树不记录前缀,只记录单点,用BIT统计前缀. 对于BIT上每一个点建一棵主席树,修改和询问的时候用BIT跑,在主席树上做就行了. 3k4人AC的题#256...应该不算慢 #incl ...
- 【分块】bzoj1901 Zju2112 Dynamic Rankings
区间k大,分块大法好,每个区间内存储一个有序表. 二分答案,统计在区间内小于二分到的答案的值的个数,在每个整块内二分.零散的暴力即可. 还是说∵有二分操作,∴每个块的大小定为sqrt(n*log2(n ...
随机推荐
- Qt-QML-关于两个平级的qml文件中的函数调用问题
这几天还在继续搞我的QML,感悟就QML是坑的同时,也是一门很号的语言,用于快速搭界面是很好的.那么,这几天, 遇到一个问题,在下用一个框框画一下,希望可以理解 抽象派,解释一下,QML1和QML3是 ...
- 180601-MySql性能监控工具MyTop
文章链接:https://blog.hhui.top/hexblog/2018/06/01/180601-MySql性能监控工具MyTop/ mysql 性能监控小工具之 mytop 参考: How ...
- Jenkins构建完成后实现自动将war包部署到指定服务器
首先我们需要确定我们的jenkins安装了:publish over ssh 插件,如果没有安装,到-->jenkins首页-->系统管理-->插件管理-->可选安装里面去搜 ...
- python程序设计——文件操作
分类 1.文本文件 存储常规字符串,由若干文本行组成,每行以换行符'\n'结尾 2.二进制文件 把对象以字节串存储,常见的图形图像.可执行文件.数据库文件office文档等 #创建文件 >> ...
- JDK源码分析:Short.java
Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short ...
- 十二:NodeManager
NM负责启动和管理节点上的containers.AM通过containers来运行任务. Health Checker Service 创建检查服务 NM运行一个检查服务来检查节点的状态,该服 ...
- 官方文档 恢复备份指南一 Introduction to Backup and Recovery
1.备份分为:物理备份和逻辑备份 物理备份:备份数据文件 控制文件 归档日志文件 逻辑备份:EXP EXPDP备份等 物理备份为主,逻辑做补充 2.错误的类型 ...
- 软工2017第四周作业结对编程——个人psp
29.22 --9.26本周例行报告 1.PSP(personal software process )个人软件过程. 类型 任务 预计时间 开始时间 结束时间 中断时间 ...
- JavaScript初探系列之数组的基本操作
在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只 ...
- DAY3敏捷冲刺
站立式会议 工作安排 (1)服务器配置 (2)数据库配置 燃尽图 燃尽图有误,已重新修改,先贴卡片的界面,后面补修改后燃尽图 代码提交记录