大三下每日打卡032

789.数的范围

给定一个按照升序排列的长度为 nn 的整数数组,以及 qq 个查询。

对于每个查询,返回一个元素 kk 的起始位置和终止位置(位置从 00 开始计数)。

如果数组中不存在该元素,则返回 -1 -1

输入格式

第一行包含整数 nn 和 qq,表示数组长度和询问个数。

第二行包含 nn 个整数(均在 1∼100001∼10000 范围内),表示完整数组。

接下来 qq 行,每行包含一个整数 kk,表示一个询问元素。

输出格式

共 qq 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 -1 -1

数据范围

1≤n≤1000001≤n≤100000 1≤q≤100001≤q≤10000 1≤k≤100001≤k≤10000

输入样例:

6 3
1 2 2 3 3 4
3
4
5

输出样例:

3 4
5 5
-1 -1
#include<iostream>
using namespace std;
const int N=1e5+5;
int n,m,q[N];
int main()
{
   scanf("%d %d",&n,&m);
   for(int i=0;i<n;i++) scanf("%d",&q[i]);
   while(m--)
  {
       int k;scanf("%d",&k);
       //寻找第一个等于K的坐标 我这边让二分的边界定为 左边为<5 右边>=5 则所求为r
       int l=-1,r=n;
       while(l+1!=r)//当l与r没有相接的时候,求边界
      {
           int mid=l+r>>1;
           //下面找第一个>=5的坐标
           if(q[mid]>=k) r=mid;
           else l=mid;
      }
       //此时得到的r是第一个>=5的坐标
       if(q[r]!=k) printf("-1 -1\n");
       else{
           printf("%d ",r);
               //现在找最后一个<=5的数字 我这边让二分的左边为<=5 右边为>5 则所求为ll
               int ll=-1,rr=n;
               while(ll+1!=rr)
              {
                   
                   int mid=ll+rr>>1;
                   if(q[mid]<=k) ll=mid;
                   else rr=mid;
              }
               if(q[ll]!=k) printf("%d\n",r);
               else printf("%d\n",ll);
          }
       
  }
   
}
 
posted @ 2025-04-10 09:16  软件拓荒人  阅读(11)  评论(0)    收藏  举报