题目:
给定一个严格单调的数列,询问若干个数分别需要在数列中二分几次才能找到。如果能找到,输出二分的次数;如果不能找到,输出 NONE
。二分查找参考程序如下:
(数列单调递增时)
l = 1, r = n, cnt = 0;
while (l <= r) {
mid = (l + r) / 2;
cnt++;
if (a[mid] == key) break;
if (a[mid] > key) r = mid - 1;
else l = mid + 1;
}
(数列单调递减时)
l = 1, r = n, cnt = 0;
while (l <= r) {
mid = (l + r) / 2;
cnt++;
if (a[mid] == key) break;
if (a[mid] > key) l = mid + 1;
else r = mid - 1;
}
上述程序中结束时 cntcnt 的值即为二分次数。
第一行两个整数 n,mn,m 分别表示数列长度和询问次数。
第二行 nn 个整数,第 ii 个表示 a_iai。
接下来 mm 行,每行一个整数 xx 表示要求询问的数。
共 mm 行,如果能找到,输出二分的次数;如果不能找到,输出 NONE
。
对于 40\%40% 的数据:1 \leq n\leq 10^6,1\leq m\leq 10^6,1\leq x,a_i\leq 10^61≤n≤106,1≤m≤106,1≤x,ai≤106。
对于 100\%100% 的数据:1\leq n\leq 10^6,1\leq m\leq 5\times 10^6,1\leq x,a_i\leq 10^61≤n≤106,1≤m≤5×106,1≤x,ai≤106。
提示:
读入/出数据量较大,请使用 scanf/printf
。
在函数声明或定义中,函数返回类型前加上关键字 inline
,即可以把函数指定为内联函数。这样可以解决一些频繁调用的函数大量消耗栈空间(栈内存)的问题,也能在一定程度上减少函数反复调用时消耗的时间。
样例1输入:
10 4
1 2 3 5 7 9 11 12 13 14
7
6
5
4
样例1输出:
1
NONE
4
NONE
(对于样例 11,77 的二分过程为 [1,10],a_5=7[1,10],a5=7。二分次数为 11;不存在 a_i=6ai=6;55 的二分过程为 [1,10],[1,4],[3,4],[4,4],a_5=5[1,10],[1,4],[3,4],[4,4],a5=5。二分次数为 44;不存在 a_i=4ai=4。)
样例2输入:
8 4
20 18 15 10 9 8 5 4
1
2
10
40
样例2输出:
NONE
NONE
1
NONE
(对于样例 22,不存在 a_i=1ai=1;不存在 a_i=2ai=2 ;1010 的二分过程为 [1,8],a_4=10[1,8],a4=10;不存在 a_i=40ai=40。)
题解:该题是二分查找的模板题,但是数据较大,读入要用快读,输出最好用printf。同时注意到,询问的数组的固定的,所以可以对数组进行提前处理并储存就不会超时啦~
代码:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int bb[1000006]={},a[1000006],n,m,e,d,c,l,r,b;
inline int read()//快读
{
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
inline void OKK(int l,int r,int h)//h是二分寻找的次数
{
if (r