题解
2026-01-04 19:11:57
发布于:上海
5阅读
0回复
0点赞
不得不承认官方给的题解还是很简洁明了的,不过在下也可以提供一种新的方法。
另一种可行思路
建立一个差分数组c,满足 ,其中 s[i] 是身高大于等于i的人数。
输入一个身高h,只需要将c[h]++,就可以构造出这个差分数组。
输入结束后只需要做c[i]+=c[i-1]遍历进行前缀和即可。
操作优化
既然我们需要构建差分数组,并在最后进行前缀和处理,我们可以用树状数组处理,每次输入身高只需要对树状数组相应位置进行+1操作即可。
注意事项
由于数据范围 ,如果不加处理就开树状数组会导致爆空间,因此需要对 和 进行离散化。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=262144;
int n,m,h[N],c[N],q,t;
int lsh[N];
int lowbit(int n){
return n&(-n);
}
int get(int id){ //查询操作
int res=0;
for(;id;id-=lowbit(id))res+=c[id];
return res;
}
void add(int id,int x){ //添加操作
for(;id<N;id+=lowbit(id))c[id]+=x;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>h[i];
lsh[i]=h[i];
}
sort(lsh+1,lsh+n+1); //排序
int len=unique(lsh+1,lsh+n+1)-lsh-1; //去重
for(int i=1;i<=n;i++)h[i]=lower_bound(lsh+1,lsh+len+1,h[i])-lsh; //离散化
for(int i=1;i<=n;i++)add(h[i],1);
while(m--){
cin>>q;
t=lower_bound(lsh+1,lsh+len+1,q)-lsh; //一样进行离散化,将离散后的值赋给新的变量t
if(q<=lsh[t])t--; //为了满足题目要求,查询身高大于等于q的人数,因此需要找到最后一个小于且不等于q的位置
//考虑到lower_bound给的结果是第一个大于等于q的位置,因此需要t--
cout<<get(n)-get(t)<<"\n"; //get(x)查询到身高大于等于x的人数,因此这边可以利用总人数减去身高小于q的人数获得答案
}
return 0;
}
这里空空如也







有帮助,赞一个