可以直接上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;
}