二逼平衡树 题解报告

先占个坑image

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+2;
int n,m,cnt,num,a[N<<1],h[N<<2],tot,n1,n2,x,y,z;
struct node{
	int fg;
	int l,r,k;
	int pos,val;
}s[N];
int w[N<<8],rt[N<<8],ls[N<<8],rs[N<<8];
int t1[N<<3],t2[N<<3];
int lowbit(int x){
	return x&(-x);
}
void add(int x,int y,int l,int r,int val){
	w[x]+=val;
	if(l==r) return ;
	int mid=(l+r)>>1;
	if(y<=mid){
		if(!ls[x]) ls[x]=++tot;
		add(ls[x],y,l,mid,val); 
	}else{
		if(!rs[x]) rs[x]=++tot;
		add(rs[x],y,mid+1,r,val);
	}
}
void update(int id,int val){
	int x=lower_bound(h+1,h+1+num,a[id])-h;
	for(int i=id;i<=n;i+=lowbit(i)){
		if(!rt[i]) rt[i]=++tot;
		add(rt[i],x,1,num,val);
	}
}
int kth(int l,int r,int k){
	if(l==r) return l;
	int sum=0,mid=(l+r)>>1;
	for(int i=1;i<=n1;i++){
		sum+=w[ls[t1[i]]];
	} 
	for(int i=1;i<=n2;i++){
		sum-=w[ls[t2[i]]];
	}
	if(sum>=k){
		for(int i=1;i<=n1;i++){
			t1[i]=ls[t1[i]];
		} 
		for(int i=1;i<=n2;i++){
			t2[i]=ls[t2[i]];
		}
		return kth(l,mid,k);
	}else{
		for(int i=1;i<=n1;i++){
			t1[i]=rs[t1[i]];
		} 
		for(int i=1;i<=n2;i++){
			t2[i]=rs[t2[i]];
		}
		return kth(mid+1,r,k-sum);
	}
} 
int query(int l,int r,int k){
	n1=n2=0;
	for(int i=r;i>0;i-=lowbit(i)){
		t1[++n1]=rt[i];
	}
	for(int i=l-1;i>0;i-=lowbit(i)){
		t2[++n2]=rt[i];
	}
	return kth(1,num,k);
}
void change(int x){
	int id=s[x].pos;
	update(id,-1);
	a[id]=s[x].val;
	update(id,1);
}
int update2(int l,int r,int k){
	if(l==r) return 0;
	int sum=0,mid=(l+r)>>1;
	for(int i=1;i<=n1;i++){
		sum+=w[ls[t1[i]]];
	} 
	for(int i=1;i<=n2;i++){
		sum-=w[ls[t2[i]]];
	}
	if(mid>=k){
		for(int i=1;i<=n1;i++){
			t1[i]=ls[t1[i]];
		} 
		for(int i=1;i<=n2;i++){
			t2[i]=ls[t2[i]];
		}
		return update2(l,mid,k);
	}else{
		for(int i=1;i<=n1;i++){
			t1[i]=rs[t1[i]];
		} 
		for(int i=1;i<=n2;i++){
			t2[i]=rs[t2[i]];
		}
		return update2(mid+1,r,k)+sum;
	}
} 
int update1(int l,int r,int kk){
	int k=lower_bound(h+1,h+1+num,kk)-h;
	n1=n2=0;
	for(int i=r;i>0;i-=lowbit(i)){
		t1[++n1]=rt[i];
	}
	for(int i=l-1;i>0;i-=lowbit(i)){
		t2[++n2]=rt[i];
	}
	return update2(1,num,k);
}
int update4(int l,int r,int k){
	int id=update1(l,r,k);
	return query(l,r,id);
}
int update7(int l,int r,int k){
	if(l==r) return 0;
	int sum=0,mid=(l+r)>>1;
	for(int i=1;i<=n1;i++){
		sum+=w[ls[t1[i]]];
	} 
	for(int i=1;i<=n2;i++){
		sum-=w[ls[t2[i]]];
	}
	if(k<mid){
		for(int i=1;i<=n1;i++){
			t1[i]=ls[t1[i]];
		} 
		for(int i=1;i<=n2;i++){
			t2[i]=ls[t2[i]];
		}
		return update7(l,mid,k);
	}else{
		for(int i=1;i<=n1;i++){
			t1[i]=rs[t1[i]];
		} 
		for(int i=1;i<=n2;i++){
			t2[i]=rs[t2[i]];
		}
		return update7(mid+1,r,k)+sum;
	}
} 
int update6(int l,int r,int kk){
	int k=lower_bound(h+1,h+1+num,kk)-h;
	n1=n2=0;
	for(int i=r;i>0;i-=lowbit(i)){
		t1[++n1]=rt[i];
	}
	for(int i=l-1;i>0;i-=lowbit(i)){
		t2[++n2]=rt[i];
	}
	return update7(1,num,k);
}
int update5(int l,int r,int k){
	int id=update6(l,r,k)+1;
	return query(l,r,id);
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]); 
		h[++cnt]=a[i];
	}	
	for(int i=1;i<=m;i++){
		int fg,pos,l,r,k;
		scanf("%d",&fg);
		if(fg==3){
			scanf("%d%d",&pos,&k);
			h[++cnt]=k;
			s[i].fg=fg;
			s[i].pos=pos;
			s[i].val=k;
		}else{
			scanf("%d%d%d",&l,&r,&k);
			s[i].fg=fg;
			s[i].l=l;
			s[i].r=r;
			s[i].k=k;
			if(fg!=2) h[++cnt]=k;
		}
	}
	sort(h+1,h+1+cnt);
	num=unique(h+1,h+1+cnt)-h-1;
	for(int i=1;i<=n;i++){
		update(i,1);
	}
	for(int i=1;i<=m;i++){
		int fg=s[i].fg;
		if(fg==1) printf("%d\n",update1(s[i].l,s[i].r,s[i].k)+1);
		if(fg==2) printf("%d\n",h[query(s[i].l,s[i].r,s[i].k)]);
		if(fg==3) change(i);
		if(fg==4) printf("%d\n",h[update4(s[i].l,s[i].r,s[i].k)]);
		if(fg==5) printf("%d\n",h[update5(s[i].l,s[i].r,s[i].k)]);
	}
	return 0;
} 

本文作者:Yvette的博客

本文链接:https://www.cnblogs.com/yvette1217/p/16353248.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   _Youngxy  阅读(46)  评论(0编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示