P2249 洛谷【深基13.例1】查找(浅谈二分查找的两个模板)

【深基13.例1】查找

P2249 【深基13.例1】查找

题目描述

输入 n ( n ≤ 1 0 6 ) n(n\le10^6) n(n106) 个不超过 1 0 9 10^9 109 的单调不减的(就是后面的数字不小于前面的数字)非负整数 a 1 , a 2 , … , a n a_1,a_2,\dots,a_{n} a1,a2,,an,然后进行 m ( m ≤ 1 0 5 ) m(m\le10^5) m(m105) 次询问。对于每次询问,给出一个整数 q ( q ≤ 1 0 9 ) q(q\le10^9) q(q109),要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 -1

输入格式

第一行 2 个整数 n 和 m,表示数字个数和询问次数。

第二行 n 个整数,表示这些待查询的数字。

第三行 m 个整数,表示询问这些数字的编号,从 1 开始编号。

输出格式

m 个整数表示答案。

样例 #1

样例输入 #1

11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6

样例输出 #1

1 2 -1

提示

1 0 6 10^6 106 规模的数据读入,请用 scanf。用 cin 会超时。

#include 
using namespace std;
const int N=1e6+5;
int n,m,x,a[N];
//二分的第一个模板
int bsearch_1(int l,int r){//从左到右找第一个大于等于x的数的编号 
	while(l<r){
		int mid=l+r>>1;
		if(a[mid]>=x) r=mid;//a[mid]在x的的右边 
		else l=mid+1;
	}
	if(a[l]==x) return l;
	else return -1;
}
//二分的第二个模板(并不适用于此题)
int bsearch_2(int l,int r){//从右到左找第一个小于等于x的数的编号 
	while(l<r){
		int mid=l+r+1>>1;
		if(a[mid]<=x) l=mid;//a[mid]在x的的左边
		else r=mid-1;
	}
	if(a[l]==x) return l;
	else return -1;
}
int main()
{
   scanf("%d %d",&n,&m);
   for(int i=1;i<=n;i++) scanf("%d",&a[i]);
   for(int i=0;i<m;i++){
   	 scanf("%d",&x);
   	 int p=bsearch_1(1,n);
   	 printf("%d ",p);
   } 
   return 0;
}

你可能感兴趣的:(刷题笔记,算法,c++,图论)