题解:洛谷 P3369【模板】普通平衡树

题解:洛谷 P3369【模板】普通平衡树

前置

需要树状数组前置知识。

思路

可以将这道题看成树状数组的题目,变得简单了点,其实是我不会写,注意到 \(|x| \le 10^7\)因为要处理负数,要加上 \(10^7+1\) ,所以可以定义数组大小为 \(2*10^7\)
而操作一、二是普通的加减,操作三是询问 \(1\)\(x-1\) 的和,操作四是询问 \(x\) 数的位置,操作五是询问 \(x-1\) 数的位置,操作六是询问 \(x+1\) 数的位置。

代码

int n;
ll f[N];
void add(ll x,int y){
	for(int i=x;i<N;i+=i&-i){
		f[i]+=y;
	}
}
int ask(ll u){
	int w=0;
	for(int i=u;i;i-=i&-i){
		w+=f[i];
	}
	return w;
}
int kth(ll x){
	int u=0;
	for(int i=1<<25;i>=1;i>>=1){
		int v=u|i;
		if(v<N&&x>f[v]){
			u=v;
			x-=f[v];
		}
	}
	return u+1;
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		ll opt, x;
		cin>>opt>>x;
		if(opt==4){
			cout<<kth(x)-10000001<<'\n';
			continue;
		}
		x+=10000001;//因为 0 在 i&-i 是死循环
		if(opt==1){
			add(x, 1);
		}
		if(opt==2){
			add(x, -1);
		}
		if(opt==3){
			cout<<ask(x-1)+1<<'\n';
		}
		if(opt==5){
			cout<<kth(ask(x-1))-10000001<<'\n';
		}
		if(opt==6){
			cout<<kth(ask(x)+1)-10000001<<'\n';
		}
	}
}

本文来自 NoiPLE ,转载请注明原文链接:https://www.cnblogs.com/noiple-dequeee/p/19576557

posted @ 2026-02-04 21:48  NoiPLE  阅读(2)  评论(0)    收藏  举报