方法描述:将查询的排序,之后扫一遍,详见代码。
#include<bits/stdc++.h>
using namespace std;
int a[1000010];
struct Question
{
int q,id;//q 表示查询的数,id 表示查询第几个(离线)
}b[100010];
int ans[100010];//每个问题的答案
bool cmp(Question a,Question b) {//对查询的数进行排序
return a.q<b.q;
}
int main() {
memset(ans,-1,sizeof(ans));//最开始都赋为 -1,查找到数时改变
int n,m,x;
cin>>n>>m;
for(register int i=0; i<n; cin>>a[++i]);
for(register int i=0; i<m; cin>>b[++i].q,b[i].id=i);
sort(b+1,b+m+1,cmp);
register int i=1,j=1;//i 为当前 a 数组查到哪个了,j 为到哪一个问题了
while(i<=n && j<=m)//当数没出,问题也没出
{
if(a[i]==b[j].q) {//如果是第一次找到
ans[b[j].id]=i;//记录答案
++j,--i;//将问题++,i 要--因为有可能查询的是同一个数
}
else if(a[i]>b[j].q) {//否则如果没找到
++j,--i;//将问题++,i--原因同上
//因为 ans 已经赋值过-1,了,所以现在不用赋
//如果之前不 memset,现在赋值,那么可能查询的数>a_max,那么会跳过,就会有问题
}
++i;
}
for(register int i=0; i<m; cout<<ans[++i],putchar(' '));
return 0;
}
现在求大佬们分析一下复杂度(是不是 O(n+mlogm))的,如果 n 很大,m 很小是不是比二分查找(O(nlogn))的更优?
求指点