【bzoj1901】dynamic ranking(带修改主席树/树套树)
题面地址(权限题)
首先说说怎么搞带修改主席树?
回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth。
那么我们如何支持修改操作?
考虑到我们之前使用主席树朴素的维护区间前缀和,支持修改的话,只要把前缀和交给擅长它的树状数组维护,主席树只要维护下大概位置就好。
当然维护位置最好要离散化一下。我校某高傲的dalao直接写CTSC那道树上动态Kth,并且niubi地手写哈希维护。

别问我了在我写这篇文章的时候他还在debug呢。
由于我比较菜,只能先把这个区间的写了,并且我太菜只能lower_bound和unique……
代码学习的网上dalao以及hzwer。
#include<bits/stdc++.h>
#define N 10005
using namespace std;
inline int lowbit(int x){return x&-x;}
int n,m,sz,totn,totx,toty,a[N],b[N<<],ca[N],cb[N],cc[N];
int xx[N],yy[N],rt[N],size[*N],ls[*N],rs[*N];
void ins(int &o,int l,int r,int x,int q,int v){
o=++sz;size[o]=size[x]+v;ls[o]=ls[x];rs[o]=rs[x];
if(l==r)return;int mid=(l+r)>>;
if(q<=mid)ins(ls[o],l,mid,ls[x],q,v);
else ins(rs[o],mid+,r,rs[x],q,v);
}
int query(int l,int r,int q){
if(l==r)return l;
int sum=,mid=(l+r)>>;
for(int i=;i<=totx;i++)sum-=size[ls[xx[i]]];
for(int i=;i<=toty;i++)sum+=size[ls[yy[i]]];
if(q<=sum){
for(int i=;i<=totx;i++)xx[i]=ls[xx[i]];
for(int i=;i<=toty;i++)yy[i]=ls[yy[i]];
return query(l,mid,q);
}
else{
for(int i=;i<=totx;i++)xx[i]=rs[xx[i]];
for(int i=;i<=toty;i++)yy[i]=rs[yy[i]];
return query(mid+,r,q-sum);
}
}
void add(int x,int v){
int k=lower_bound(b+,b+totn+,a[x])-b;
for(int i=x;i<=n;i+=lowbit(i))ins(rt[i],,totn,rt[i],k,v);
}
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int main(){char s[];
n=read();m=read();
for(int i=;i<=n;i++)a[i]=read(),b[++totn]=a[i];
for(int i=;i<=m;i++){
scanf("%s",s);ca[i]=read();cb[i]=read();
if(s[]=='Q')cc[i]=read();else b[++totn]=cb[i];
}
sort(b+,b+totn+);
totn=unique(b+,b+totn+)-b-;
for(int i=;i<=n;i++)add(i,);
for(int i=;i<=m;i++){
if(cc[i]){
totx=toty=;
for(int j=ca[i]-;j;j-=lowbit(j))xx[++totx]=rt[j];
for(int j=cb[i];j;j-=lowbit(j))yy[++toty]=rt[j];
printf("%d\n",b[query(,totn,cc[i])]);
}
else{add(ca[i],-);a[ca[i]]=cb[i];add(ca[i],);}
}
}
啊当然树套树也是可以的啦。
#include<bits/stdc++.h>
#define N 200001
#define M 1300001
#define inf 1000000007
using namespace std;
int n,m,tmp,a[N>>],rt[N],sz,size[M],ls[M],rs[M],val[M],w[M],rnd[M];
inline void pushup(int x){
//in Treap
size[x]=size[ls[x]]+size[rs[x]]+w[x];
}
void rturn(int &k)
{int t=ls[k];ls[k]=rs[t];rs[t]=k;size[t]=size[k];pushup(k);k=t;}
void lturn(int &k)
{int t=rs[k];rs[k]=ls[t];ls[t]=k;size[t]=size[k];pushup(k);k=t;}
void ins(int &k,int x){// in Treap
if(!k){
k=++sz;size[k]=;w[k]=;ls[k]=;rs[k]=;rnd[k]=rand();val[k]=x;return;
}
size[k]++;if(val[k]==x)w[k]++;
else if(x<val[k]){ins(ls[k],x);if(rnd[ls[k]]<rnd[k])rturn(k);}
else{ins(rs[k],x);if(rnd[rs[k]]<rnd[k])lturn(k);}
}
void del(int &k,int x){// in Treap
if(val[k]==x){
if(w[k]>){w[k]--;size[k]--;return;}
if(ls[k]*rs[k]==)k=ls[k]+rs[k];
else if(rnd[ls[k]]<rnd[rs[k]]){rturn(k);del(k,x);}
else{lturn(k);del(k,x);}
}
else if(x<val[k]){del(ls[k],x);size[k]--;}
else{del(rs[k],x);size[k]--;}
} void change(int o,int l,int r,int q,int num,int v){
// in Segment Tree
del(rt[o],v);ins(rt[o],num);
if(l==r)return;
int mid=(l+r)>>;
if(q<=mid)change(o<<,l,mid,q,num,v);
else change(o<<|,mid+,r,q,num,v);
}
void build(int o,int l,int r,int q,int num){
ins(rt[o],num);if(l==r)return;
int mid=(l+r)>>;
if(q<=mid)build(o<<,l,mid,q,num);
else build(o<<|,mid+,r,q,num);
}
void find(int k,int x){
if(!k)return;
if(val[k]<=x){tmp+=size[ls[k]]+w[k];find(rs[k],x);}
else find(ls[k],x);
}
void query(int o,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr){find(rt[o],v);return;}
int mid=(l+r)>>;
if(ql<=mid)query(o<<,l,mid,ql,qr,v);
if(qr>mid)query(o<<|,mid+,r,ql,qr,v);
}
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
char s[];
int main(){
int T=read();
while(T--){
memset(rt,,sizeof(rt));sz=;
n=read();m=read();
for(int i=;i<=n;i++)a[i]=read();
for(int i=;i<=n;i++)build(,,n,i,a[i]);
for(int i=;i<=m;i++){
scanf("%s",s);
if(s[]=='C'){
int x=read(),y=read();
change(,,n,x,y,a[x]);
a[x]=y;
}
else{
int x=read(),y=read(),z=read();
int l=,r=inf;
while(l<=r){
int mid=(l+r)>>;
tmp=;query(,,n,x,y,mid);
if(tmp>=z)r=mid-;else l=mid+;
}
printf("%d\n",l);
}
}
}
return ;
}
其实这个树套树只要分清楚维护范围,也不是很难写的那种。
不过对于这种恶心的数据结构题,整体二分也是可以做到的。
这里是will大爷写的整体二分的题解。

【bzoj1901】dynamic ranking(带修改主席树/树套树)的更多相关文章
- BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树
题目: emmmm是个权限题 题解: 带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改 修改的时候修改类似树状数组一样进行logn个Insert 查询的时候同理,树状数组的方法 ...
- Luogu Dynamic Ranking (带修改的主席树)
题目大意: 网址:https://www.luogu.org/problemnew/show/2617 给定一个序列a[1].a[2].....a[N],完成M个操作,操作有两种: [1]Q i j ...
- BZOJ1901 Dynamic Rankings|带修主席树
题目链接:戳我 其实我并不会做,于是看了题解 我们都知道主席树是利用前缀和记录历史版本来搞区间K大的一种数据结构.不过一般的主席树只能搞定静态区间第K大.如果带修怎么办呢? 想一下...单点修改+区间 ...
- 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小
少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...
- [BZOJ3295] [Cqoi2011]动态逆序对(带修改主席树)
题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序 ...
- BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序
Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路 ...
- 【bzoj1901】dynamic ranking(带修改主席树)
传送门(权限) 传送门(非权限) 花了一晚上总算把代码调好了……才知道待修改主席树怎么操作…… 然而还是一知半解orz…… 先说说我的理解吧 我们一般建主席树的时候都是直接在序列上建的 但是如果有修改 ...
- BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】
1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 7143 Solved: 2968[Su ...
- [luogu P2617] Dynamic Rankings 带修主席树
带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...
随机推荐
- [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)
目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...
- POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)
POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Networ ...
- [luogu2114][起床困难综合症]
luogu2114 思路 因为位运算对于每一位是独立的,所以对每一位都对这n个数进行操作,然后观察最后得出的是1还是0.并且保证每一位拼起来之后要比m小. 代码 #include<cstdio& ...
- asp <----> vb(com,dll) <---> c 来回的调用,生命在于折腾
最近想改进一个两年前写的小程序,原因是最近将运行在托管服务器上的asp程序迁移到阿里云主机上运行. 初次使用阿里云主机,买了一个配置较低的主机(1核,1G内存,年付:1500左右吧) 原来使用的托管的 ...
- BRIEF特征简介
引言 该文是由EPFL的Calonder在ECCV2010上提出了一种可以快速计算且表达方式为二进制编码的描述子.主要思路就是在特征点附近随机选取若干点对,将这些点对的灰度值的大小,组合成一个二进制串 ...
- 数据类型、位运算、sizeof()函数
数据精度,依次升高.(负数必须使用有符号类型) 不同精度的数据间运算,所得结果为高精度类型. 数据类型详细信息如下图: 整型数据的数制:十进制(32).八进制(032,以0开头).十六进制(0x32, ...
- C# TextBox猜想输入和历史记录输入
什么是猜想输入 当我们在使用查询应用时,输入某个关键字后文本框下面就会自动弹出跟此关键字相附的词组供我们选择,为我们节省了输入的时间,这就是猜想输入,例如:百度,谷歌,等等,如下图: 如上图所示,使用 ...
- 2018acm-icpc宁夏邀请赛后记
由于要准备期末考试的缘故,时隔一个月之后我才想起来还有一场比赛没有总结. 大概是出去过的最远的地方了,宁夏理工学院离杭州有两千多千米. 不得不说感到了主办方满满的诚意,虽然是第一次办比赛,但是第一天组 ...
- 因缺失log4j.properties 配置文件导致flume无法正常启动。
因缺失log4j.properties 配置文件导致flume无法正常启动 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.报错:log4j:WARN No appenders ...
- 获取当前操作系统的ip
代码如下: #include "stdafx.h" #include <WinSock2.h> int get_local_ip() { WSADATA wsaData ...