论如何在无序序列logn找到第一个大于等于x的数
  • 板块灌水区
  • 楼主xiao7_Mr_10_
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/12/21 17:23
  • 上次更新2023/12/21 17:29:31
查看原帖
论如何在无序序列logn找到第一个大于等于x的数
961149
xiao7_Mr_10_楼主2023/12/21 17:23

可以直接上st表分类讨论或者线段树,但都太麻烦了,其实可以这样:

对于一个区间(l,r)我们令mid=(l+r)/2,则如果l,mid之间的数的最大值大于了x就在l,mid里找,反之依然,如果l,r都没有的话就说明没有

贴代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,a[N],st[N][20],logn;
int query(int l,int r){
	int logx=log2(r-l+1);
	return max(st[l][logx],st[r-(1<<logx)+1][logx]);
}
int find(int l,int r,int x){
	int mid=(l+r)>>1;
	if(l==r&&a[l]>=x)return l;
	int max1=query(l,mid),max2=query(mid+1,r);
	if(max1>=x)return find(l,mid,x);
	else if(max2>=x)return find(mid+1,r,x);
	else return -1;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	logn=log2(n);
	for(int i  =1;i <= n;i++)cin >> a[i],st[i][0]=a[i];
	for(int j = 1;j <= logn;j++)
		for(int i = 1;i <= n;i++)
			st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
	//find(l,r,x)意思是在[l-r]找到第一个大于等于x的数,没有就输出-1,如果要支持修改就把st表改成线段树 
	return 0;
}
2023/12/21 17:23
加载中...