P3369 【模板】普通平衡树 线段树

 

#include<bits/stdc++.h>
using namespace std;
const int N=10000010;
int T[N<<3];
void update(int p,int v,int rt,int l,int r)
{
	T[rt]+=v;
	if (l==r) return ;
	int m=l+(r-l)/2;
	if (p<=m) update(p,v,rt<<1,l,m);
	else update(p,v,rt<<1|1,m+1,r);
}
int kth(int k,int rt,int l,int r)
{
	if (l==r) return l;
	int m=l+(r-l)/2;
	if (T[rt<<1]>=k) return kth(k,rt<<1,l,m);
	return kth(k-T[rt<<1],rt<<1|1,m+1,r);
}
int Rank(int pl,int pr,int rt,int l,int r)
{
	if(pl<=l&&r<=pr) return T[rt];
	int m=l+(r-l)/2;
	int res=0;
	if (pl<=m)res+=Rank(pl,pr,rt<<1,l,m);
	if (m<pr) res+=Rank(pl,pr,rt<<1|1,m+1,r);
	return res; 
}
int pre(int pl,int pr,int rt,int l,int r)
{
	return kth(Rank(pl,pr-1,1,l,r),1,l,r);
}
int nxt(int pl,int pr,int rt,int l,int r)
{
	return kth(Rank(pl,pr,1,l,r)+1,1,l,r);
}
int op[N],a[N];
int main()
{
	int n;
	cin>>n;
	int xmin=0x7fffffff,xmax=0x80000000;
	for (int i=1;i<=n;i++)
	{
		cin>>op[i]>>a[i];
		xmin=min(a[i],xmin);
		xmax=max(xmax,a[i]);
	}
	for(int i=1;i<=n;i++)
	{
		if (op[i]==1)
			update(a[i],1,1,xmin,xmax);
		else if(op[i]==2)
			update(a[i],-1,1,xmin,xmax);
		else if (op[i]==3)
		{
			if (a[i]==xmin)
			{
				cout<<1<<endl;
			}
			else
			{
				cout<<Rank(xmin,a[i]-1,1,xmin,xmax)+1<<endl;
			}
		}
		else if(op[i]==4)
		{
			cout<<kth(a[i],1,xmin,xmax)<<endl;
		}
		else if(op[i]==5)
		{
			cout<<pre(xmin,a[i],1,xmin,xmax)<<endl;
		} 
		else
		{
			cout<<nxt(xmin,a[i],1,xmin,xmax)<<endl;
		}
	}
	return 0;
}
/*
9
-90 56 34 12 567 34 23 12 89

9
-10000000 90 10000000 89 67 56 -9 12 -1000

*/ 

  

posted @ 2022-03-17 23:09  心悟&&星际  阅读(35)  评论(0编辑  收藏  举报