二分查找 查找非常大的数中的非常多的数


//当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 ",f,k);//输出的是左闭右开
            printf("%d ",k-f);//输出v的个数
        }
        else printf("不存在v ");
    }
    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 ",j,j+cnt,cnt);//输出左闭右开以及个数
//        else printf("不存在v ");
//    }
//    return 0;
//}



原文地址:https://www.cnblogs.com/nyist-xsk/p/7264895.html