时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld
题目描述
一个长度为n的数组a,数组下标从0开始。现在要求你查询从左到右第一个不小于k的数字a[i], 输出i,并且马上把a[i-1]++;如果你找到的a[i]中的i等于0,那么a[0-1]是非法的,因此只要输出i就行了,不进行a[i-1]++;如果你在数组中找不到一个数字不小于k,则输出”are you ok ”
输入描述:
多组输入,输入直到遇到EOF为止;
第一行输入两个整数n和q,表示数组a中有n个整数,q表示q次查询;
第二行输入n个整数;
第三行到后2+q行,每行输入一个数字k,表示要求你查询从左到右第一个不小于k的数字并马上输出。
注意:1 < n, q <= 1e6, a[i]和k是一个int型的整数
输出描述:
见输入。
示例1
输入
3 4
1 2 8
2
2
8
9
输出
1
0
2
are you ok
由题意可知,维护一个数组maxi【i】表示【1,i】的最大值,二分查找k,然后更新。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
int maxi[maxn],a[maxn];
int main()
{
int n,q,k;
while(scanf("%d%d",&n,&q)==2)
{
int _max=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
if(a[i]>_max) _max=a[i];
maxi[i]=_max;
}
while(q--)
{
scanf("%d",&k);
if(k>_max)
{
printf("are you ok\n");
continue;
}
int pos=lower_bound(maxi,maxi+n,k)-maxi;
if(!pos)
{
printf("0\n");
continue;
}
printf("%d\n",pos);
a[pos-1]++;
if(a[pos-1]>maxi[pos-1]) maxi[pos-1]=a[pos-1];
}
}
}