输入 $n$ 个不超过 $10^9$ 的单调不减的(就是后面的数字不小于前面的数字)非负整数 $a_1,a_2,\dots,a_{n}$,然后进行 $m$ 次询问。对于每次询问,给出一个整数 $q$,要求输出这个数字在序列中第一次出现的编号,如果没有找到的话输出 $-1$ 。
第一行 $2$ 个整数 $n$ 和 $m$,表示数字个数和询问次数。
第二行 $n$ 个整数,表示这些待查询的数字。
第三行 $m$ 个整数,表示询问这些数字的编号,从 $1$ 开始编号。
输出一行,$m$ 个整数,以空格隔开,表示答案。
11 3
1 3 3 3 5 7 9 11 13 15 15
1 3 6
1 2 -1
数据保证,$1 \leq n \leq 10^6$,$0 \leq a_i,q \leq 10^9$,$1 \leq m \leq 10^5$
本题输入输出量较大,请使用较快的 IO 方式。
#include
using namespace std;
const int N = 10000005;
int arr[N];
int main(){
int n,m;
scanf("%d%d\n",&n,&m);
for(int i = 1; i <= n; i++){
scanf("%d",&arr[i]);
}
for(int j = 1; j <= m; j++){
int left = 1;
int right = n;
int mid = (left + right) / 2;
int x;
scanf("%d",&x);
while(true){
if(arr[mid] > x){
right = mid - 1;
mid = (left + right) / 2;
}
if(arr[mid] < x){
left = mid + 1;
mid = (left + right) / 2;
}
if(arr[mid] == x) {
break;
}
if(left > right) {
printf("%d",-1);
return 0;
}
}
int b = 0;
for(int i = 1; i < mid; i++){
if(arr[mid-i]==arr[mid]) {
b++;
}
else break;
}
printf("%d ",mid-b);
}
return 0;
}
代码
int n,i_count;
scanf("%d%d",&n,&i_count);
int a[n+1];
for(int i=0;i<n;++i)
{
scanf("%d",&a[i]);
}
for(int i=0;i<i_count;++i)
{
int k;
scanf("%d",&k);
int left=0,right=n-1;
bool isFind=false;
while(left<right)
{
int mid=left+(right-left)/2;
if(a[mid]==k)
{
while(a[mid]==k)
{
--mid;
}
isFind=true;
printf("%d ",mid+2);
break;
}
else if(a[mid]<k)
{
left=mid+1;
}
else
{
right=mid-1;
}
}
if(!isFind)
printf("%d ",-1);
}