树状数组与离散化与求第K大模板

树状数组模板:

//Cnt为数组的界
//cnt[i]为编号或者数值上小于id的数量
void Update(LL Id)
{
	while(Id<=Cnt)
	{
		cnt[Id]++;
		Id+=lowbit(Id);
	}
}
LL num(LL Id)
{
	LL ans=0;
	while(Id>0)
	{
		ans+=cnt[Id];
		Id-=lowbit(Id);
	}
	return ans;
}

离散化

//arr为保存原数据的数组
//id为保存新的ID的数组
sort(arr+1,arr+1+n);
Cnt=unique(arr+1,arr+1+n)-arr-1;
for(LL i=1;i<=n;i++) id[i]=lower_bound(arr+1,arr+1+Cnt,p[i].x)-arr;

求第K大的模板

void add(int x,int val)
{
	while(x<size)
	{
		c[x]+=val;
		x+=lowbit(x);
	}
}
int sum(int x)
{
	int ans=0;
	while(x)
	{
		ans+=c[x];
		x-=lowbit(x);
	}
	return ans;
}
//以上为树状数组的常规代码
int query(int k)
{
	int ans=0,cnt=0;
	for(int i=20;i>=0;i--)
	{
		
		ans+=(1<<i);
//这里使用了二进制的思想,去卡那个目标的第k大,当ans小于第K大时,ans就会增加,当ans大于等于第K大
//时,ans就放弃这次增加,这样最后得到的ans必然是第K大-1
		if(ans>=maxn||cnt+c[ans]>=k)
		{
			ans-=(1<<i);
		}
		else
		{
			cnt+=c[ans];
		}
		
	}
	return ans+1;
}

猜你喜欢

转载自blog.csdn.net/baiyifeifei/article/details/81664956