萌新刚学OI1ms,求助权值线段树
查看原帖
萌新刚学OI1ms,求助权值线段树
87434
_Life_楼主2021/3/22 20:46

RT 样例都过不去QAQ

因为是平衡树模板所以要用线段树写

#include<map>
#include<cstdio>
#include<algorithm>
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
int n;
int sum[100001<<2];
void ins(int k,int v,int pos=1,int l=1,int r=n)
{
	sum[pos]+=v;
	if(l==r)
		return;
	int m=(l+r)>>1;
	if(k<=m)
		ins(k,v,ls(pos),l,m);
	else
		ins(k,v,rs(pos),m+1,r);
}
int rank(int k,int pos=1,int l=1,int r=n)//sum(1...k-1)
{
	if(r<k)
		return sum[pos];
	int ans=0,m=(l+r)>>1;
	ans+=rank(k,ls(pos),l,m);
	if(m<k-1)
		ans+=rank(k,rs(pos),m+1,r);
	return ans;
}
int kth(int k,int pos=1,int l=1,int r=n)
{
	if(l==r)
		return l;
	int m=(l+r)>>1;
	if(sum[ls(pos)]>=k)
		return kth(k,ls(pos),l,m);
	else
		return kth(k-sum[ls(pos)],rs(pos),m+1,r);
}
int a[100001],b[100001],c[100001];
std::map <int,int> mp;
int main()
{
	int m;
	scanf("%d",&m);
	//离散化
	for(int i=1;i<=m;i++)
		scanf("%d %d",&a[i],&b[i]),c[i]=b[i];
	std::sort(c+1,c+1+m);
	n=std::unique(c+1,c+1+m)-(c+1);
	for(int i=1;i<=n;i++)
		mp[c[i]]=i;
	for(int i=1;i<=m;i++)
	{
		int op=a[i],x=mp[b[i]];
		if(op==1)ins(x,1);
		if(op==2)ins(x,-1);
		if(op==3)printf("%d\n",rank(x));
		if(op==4)printf("%d\n",c[kth(x)]);
		if(op==5)printf("%d\n",c[kth(rank(x)-1)]);
		if(op==6)printf("%d\n",c[kth(rank(x)+1)]);
	}
	printf("%d",kth(1));
}
2021/3/22 20:46
加载中...