题面地址(权限题)

不用权限题的地址

首先说说怎么搞带修改主席树?

回忆一般的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(带修改主席树/树套树)的更多相关文章

  1. BZOJ 1901: Zju2112 Dynamic Rankings | 带修改主席树

    题目: emmmm是个权限题 题解: 带修改主席树的板子题,核心思想是用树状数组维护动态前缀和的性质来支持修改 修改的时候修改类似树状数组一样进行logn个Insert 查询的时候同理,树状数组的方法 ...

  2. Luogu Dynamic Ranking (带修改的主席树)

    题目大意: 网址:https://www.luogu.org/problemnew/show/2617 给定一个序列a[1].a[2].....a[N],完成M个操作,操作有两种: [1]Q i j ...

  3. BZOJ1901 Dynamic Rankings|带修主席树

    题目链接:戳我 其实我并不会做,于是看了题解 我们都知道主席树是利用前缀和记录历史版本来搞区间K大的一种数据结构.不过一般的主席树只能搞定静态区间第K大.如果带修怎么办呢? 想一下...单点修改+区间 ...

  4. 少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小

    少年,想学带修改主席树吗 | BZOJ1901 带修改区间第k小 有一道题(BZOJ 1901)是这样的:n个数,m个询问,询问有两种:修改某个数/询问区间第k小. 不带修改的区间第k小用主席树很好写 ...

  5. [BZOJ3295] [Cqoi2011]动态逆序对(带修改主席树)

    题目描述 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序 ...

  6. BZOJ 1146: [CTSC2008]网络管理Network 带修改主席树_树套树_DFS序

    Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路 ...

  7. 【bzoj1901】dynamic ranking(带修改主席树)

    传送门(权限) 传送门(非权限) 花了一晚上总算把代码调好了……才知道待修改主席树怎么操作…… 然而还是一知半解orz…… 先说说我的理解吧 我们一般建主席树的时候都是直接在序列上建的 但是如果有修改 ...

  8. BZOJ 1901: Zju2112 Dynamic Rankings[带修改的主席树]【学习笔记】

    1901: Zju2112 Dynamic Rankings Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 7143  Solved: 2968[Su ...

  9. [luogu P2617] Dynamic Rankings 带修主席树

    带修改的主席树,其实这种,已经不能算作主席树了,因为这个没有维护可持久化的... 主席树直接带修改的话,由于这种数据结构是可持久化的,那么要相应改动,这个节点以后所有的主席树,这样单次修改,就达到n* ...

随机推荐

  1. linux ssh keys

    1. 原理: SSH 密钥对总是成双出现的,一把公钥,一把私钥.公钥可以自由的放在您所需要连接的 SSH 服务器上,而私钥必须稳妥的保管好. 所谓"公钥登录",原理很简单,就是用户 ...

  2. 在任意位置获取应用程序CONTEXT

    Android程序中访问资源时需要提供Context,一般来说只有在各种component中(Activity, Provider等等)才能方便的使用api来获取Context, 而在某些工具类中要获 ...

  3. forEach、for、$.each()跳出循环比较

    无论工作上或是学习上,用过的知识点总是容易忘记,于是略作记录,方便你我他. 说起跳出循环,第一时间想起的是 break \ continue,这是经典的for循环. 1.for 循环 先上例子,思考输 ...

  4. 树莓派上使用DHCPig进行DHCP池耗尽攻击

    安装DHCPig 这个工具依赖Python的Scapy包,如果未安装需要使用pip工具安装. wget https://github.com/kamorin/DHCPig/raw/master/pig ...

  5. Some Interesting Problems(持续更新中)

    这种题目详解,是“一日一测”与“一句话题解”栏目所无法覆盖的,可能是考试用题,也可能是OJ题目.常常非常经典,可以见微知著.故选其精华,小列如下. T1:fleet 给定一个序列,询问[L,R]间有多 ...

  6. 决策单调性优化dp

    决策单调性: 对于一些dp方程,经过一系列的猜想和证明,可以得出,所有取的最优解的转移点(即决策点)位置是单调递增的. 即:假设f[i]=min(f[j]+b[j]) (j<i) 并且,对于任意 ...

  7. 【codevs2189】数字三角形+

    题目大意:给定一个数字三角形,求从 (1,1) 走到最后一行的路径和对 100 取余数的最大值. 题解:由于最优解涉及到取余数的操作,因此按照原先的状态设计并不符合最优子结构性质,即:两个最大数相加取 ...

  8. [luoguU42591][小T的面试题]

    luoguU42591 题意: n个不超过n的正整数中,其中有一个数出现了两次,其余的数都只出现了一次, 求这个出现两次的数. 思路: 这个题的亮点在于内存限制1MB.明显不能再用数组储存了,肯定是用 ...

  9. bug6 项目检出JRE问题(Unbound classpath container: 'JRE System Library [JavaSE-1.7]' in project 'idweb')

    项目从SVN检出到工作空间后报了很多错误,其中很明显就是一些jar的问题,没有相关的jar或版本问题,看到最后的错误Unbound classpath Container: 'JRE System L ...

  10. VUE在BODY上绑定enter事件

    mounted () { this.bodyListener = (e) => { if (e.keyCode === 13 && e.target === document.b ...