二分查找 查找非常大的数中的非常多的数
//当m高达10的6次方以上且要查的数非常多的话的话,用二分查找不超时
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m;
int a[110];
int lower_bound(int* A,int x,int y,int v)//求下限
{
int m;
while(x<y)
{
m=x+(y-x)/2;
if(A[m]>=v) y=m;
else x=m+1;
}
return x;
}
int upper_bound(int* A,int x,int y,int v)//求上限
{
int m;
while(x<y)
{
m=x+(y-x)/2;
if(A[m]<=v) x=m+1;
else y=m;
}
return y;
}
int main()
{
int i,j,f,k,v,flag;
scanf("%d",&n);
while(n--)
{
flag=0;
scanf("%d",&m);
for(i=0; i<m; i++)
scanf("%d",&a[i]);
sort(a,a+m);
scanf("%d",&v);
for(i=0; i<m; i++)
if(a[i]==v)
{
flag=1;
break;
}
f=lower_bound(a,0,m,v);
k=upper_bound(a,0,m,v);
if(flag)
{
printf("%d %d\n",f,k);//输出的是左闭右开
printf("%d\n",k-f);//输出v的个数
}
else printf("不存在v\n");
}
return 0;
}
//如果m非常大的话,这种方法可能超时
//适合单次查找
//#include<stdio.h>
//#include<algorithm>
//#include<string.h>
//#include<iostream>
//using namespace std;
//
//int n,m,v;
//int a[110];
//
//int main()
//{
// scanf("%d",&n);
// while(n--)
// {
// int i,j,cnt=0,flag=0;
// scanf("%d",&m);
// for(i=0; i<m; i++)
// scanf("%d",&a[i]);
// sort(a,a+m);
// scanf("%d",&v);
// for(i=0; i<m; i++)
// {
// if(a[i]==v)
// {
// j=i;
// flag=1;
// break;
// }
// }
// for(i=0; i<m; i++)
// {
// if(a[i]==v)
// {
// ++cnt;
// }
// }
// if(flag)
// printf("%d %d %d\n",j,j+cnt,cnt);//输出左闭右开以及个数
// else printf("不存在v\n");
// }
// return 0;
//}