789.数的范围

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n,k;
int p[N];
using namespace std;
// 二分的本质:  整数二分法 
// 找到一个性质,这个性质可以吧区间分成两半 
//   |  -----------------|←左    右→|---------------------| 
// 既可以找到左边的边界又可以找到右边的边界 
// ①mid =l+r+1/2 先判断是否符合左半边的性质 
// ②先进行check(mid)的判断,if(true){ mid就在左半边,但是答案区间在[mid,r]} 
//                          else{ mid就在右面这个性质上,因此mid在左面的区间上,答案就在[l,mid-1]}
//                          为什么else语句将要进行mid-1,因为此时的mid并不符合左边区间的性质条件
// ③mid = l+r/2 然后判断是否符合右面区间的性质 
//                          if(true)那么表明mid符合右半边的性质,因此mid在右区间,因此答案就在[l,mid]
//                          else { mid就在左半边的区域上,答案就在[mid+1,r]} 

//分析为什么第一种情况的时候为什么还要在加上一个1,因为当mid=l+r/2,l=r-1的时候,那么mid=l,因此遍历的区间仍是[l,r]就会陷入
//到死循环的境地 

int main(){
    
    cin>>n>>k;
    for(int i=0;i<n;i++){
        scanf("%d",&p[i]);
    }
    
    while(k--){
        int x;
        cin>>x;
        int l = 0,r=n-1;
        while(l<r)
        {
            int mid = (l+r)>>1;//二进制往右移是除以二
            if(p[mid]>=x)//寻找开始的节点,那么就应该覆盖右侧的重复的区域
               r = mid;
            else l = mid+1;
        }
        if(p[l]!=x)
          cout<<"-1 -1"<<endl;
        else{
           cout<<l;
           l= 0,r=n-1;
           while(l<r){
               int mid = (l+r+1)>>1;
               if(p[mid]<=x) 
                 l = mid;
               else
                 r = mid-1; 
           }
           cout<<" "<<l<<endl;
        }
    }
    
    return 0;
}




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值