#5012. 2026/2/26/LH笔记(二分查找)

2026/2/26/LH笔记(二分查找)

当前没有测试数据。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int t, n, a[N];
//结构体排序中经典问题
//利用结构体排序 计算每个学生的排名
struct st {
	int id, fs, pm, wz;
	string name;
} s[N];
int n;
bool cmp(st s1, st s2){return s1.fs > s2.fs;}
//如果我可以想办法把奶牛的编号缩小
//满足 如果缩小前编号不一样 缩小后 编号一定不一样
//如果缩小前编号相同 缩小后编号一定也相同
//把每一头奶牛 按照编号排序 从大到小排序
//如果编号相同 那排名就相同
//二分查找  binary search  bs
//二分查找的前提条件是  数组有序
//假设现在有一个数组a  长度是1e6  a数组有序
//现在有1e5次查询 每次查询给你一个数字
//如果这个数字在数组出现过 输出YES 没出现过 输出NO
//二分查找特点:思想非常好理解,但是代码细节比较多
//初学者很容易写错
//二分查找 4种模板 7种题型
//左闭右闭 左闭右开 左开右闭 左开右开
//如果包含端点  叫做闭
//如果不包含端点 叫做开
//编程小技巧:C++默认向下取整
//如何快速的向上取整呢???
//(a+b-1)/b 这个就是a/b向上取整的结果
//a是b的倍数  a/b   a不是b的倍数
//二分查找-类型1(查找某个数字是否出现过)
//在有序的a数组里面查找数字x有没有出现
int bs1(int x){
	int l = 1, r = n;
	while (l <= r){
		int mid = (l + r) / 2;
		if (a[mid] == x) return 1;
		if (a[mid] > x) r = mid - 1;
		if (a[mid] < x) l = mid + 1;
	}
	return 0;
}
// 二分查找-类型2(查找某个数字第一次出现的位置)
int bs2(int x){
	int l = 1, r = n, ans =-1;
	//ans用来记录第一个x出现的位置
	while (l <= r){
		int mid = (l + r) / 2;
		if (a[mid] == x) ans = mid, r = mid - 1;
		if (a[mid] > x) r = mid - 1;
		if (a[mid] < x) l = mid + 1;
	}
	return ans;
}
//二分查找-类型3(查找某个数字最后一次出现的位置)
//结合类型2和类型3  我们可以快速的查询某个数字的出现次数
//二分查找-类型4(查找大于k的第一个位置)
int bs4(int k){
	int l = 1, r = n, ans =-1;
	//ans用来记录大于k的第一个位置
	while (l <= r){
		int mid = (l + r) / 2;
		if (a[mid] > k) ans = mid, r = mid - 1;
		else l = mid + 1;
		//这个else是把  a[mid]==k和a[mid]<k
	}
	return ans;
}
//利用类型4 我们可以快速的查找在a数组里面有几个数字大于k
//二分查找-类型5(查找大于等于k的第一个位置)
int bs5(int k){
	int l = 1, r = n, ans =-1;
	//ans用来记录大于k的第一个位置
	while (l <= r){
		int mid = (l + r) / 2;
		if (a[mid] >= k) ans = mid, r = mid - 1;
		else l = mid + 1;
		//这个else是把  a[mid]==k和a[mid]<k
	}
	return ans;
}
//二分查找-类型6(查找小于k的最后一个位置)
int bs6(int k){
	int l = 1, r = n, ans =-1;
	while (l <= r){
		int mid = (l + r) / 2;
		if (a[mid] < k) ans = mid, l = mid + 1;
		else r = mid - 1;
	}
	return ans;
}
//我们可以利用类型6快速的查询 小于某个数字 有多少个
//二分查找-类型7(查找小于等于k的最后一个位置)
int bs7(int k){
	int l = 1, r = n, ans =-1;
	while (l <= r){
		int mid = (l + r) / 2;
		if (a[mid] <= k) ans = mid, l = mid + 1;
		else r = mid - 1;
	}
	return ans;
}
int main(){
	cin >> n;
	for (int i = 1; i <= n; i++){
		cin >> s[i].id >> s[i].name >> s[i].fs;
		s[i].wz = i;
	}
	sort(s + 1, s + 1 + n, cmp);
	for (int i = 1; i <= n; i++){
		if (s[i].fs == s[i - 1].fs) s[i].pm = s[i - 1].pm;
		else s[i].pm = i;
	}
	return 0;
}