树状数组与离散化与求第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;
}