P3369 【模板】普通平衡树 树状数组


#include
#include
using namespace std;
const int Maxn=10000000;
int tr[2*Maxn+10];
int lowbit(int x)
{
	return x&(-x);
}
void add(int x)
{
	x+=Maxn;x++;
	while (x<=Maxn*2+9)
	{
		tr[x]++;
		x=x+lowbit(x);
	}
}
void dele(int x)
{
	x+=Maxn;x++;
	while(x<=Maxn*2+9)
	{
		tr[x]--;
		x=x+lowbit(x);
	}
}
int getsum(int x)
{
	x+=Maxn;x++;
	int ans=0;
	while(x)
	{
		ans+=tr[x];
		x=x-lowbit(x);
	}
	return ans;
}
//x的排名 
int getk(int x)
{
	return getsum(x);
}
//排名为x的是谁? 
int rank(int x)
{
	int left=-1e7,right=1e7;
    while(left!=right){
        int mid=(left+right)>>1;
        int m=getsum(mid);
        if(m>=x)right=mid;
        else left=mid+1;
    }
    return left;
}
int pre(int x)
{
	return rank(getk(x-1));
}
int suc(int x)
{
	return rank(getk(x)+1);
}
int main()
{
	int n;
	scanf("%d",&n);
	while(n--)
	{
		int opt,x;
		scanf("%d%d",&opt,&x);
		switch(opt)
		{
			case 1:
				{
					add(x);
					break;
				}
			case 2:
				{
					dele(x);
					break;
				}
			case 3:
				{
					printf("%d\n",getk(x-1)+1);
					break;
				}
			case 4:
				{
					printf("%d\n",rank(x));
					break;
				}
			case 5:
				{
					printf("%d\n",pre(x));
					break;
				}
			case 6:
				{
					printf("%d\n",suc(x));
					break;
					
				}
			
		}
	}
}