HDU 2141 Can you find it?(二分)

题目大意:有a,b,c三个数,接下来分别代表a,b,c集合中的元素然后又有m行询问,问能不能在a,b,c每行取一个数组成x。

思路:肯定是二分,但是注意在二分的时候应该二分a[i]+b[j]的值因为和会有500*500个,然后再在外边套循环,并且要用LL!

    #include<map>
    #include<queue>
    #include<cmath>
    #include<iostream>
    #include<cstdio>
    #include<stack>
    #include<cstring>
    #include<algorithm>
    #define LL __int64
    #define inf 0x3f3f3f3f
    #define eps 1e-5
    #define fr freopen("dabiao.txt","w",stdout);
    const double PI=acos(-1.0);
    using namespace std;
    LL a[100100],b[100100],c[100100],q[567890];

    int main(){
        LL n,m,i,j,k,z,cla=0,t,s;
        while(~scanf("%I64d %I64d %I64d",&n,&m,&z)){
            s=0;
            for(i = 0;i < n ; ++ i)
                scanf("%I64d",&a[i] );
            for(i = 0;i < m ; ++ i)
                scanf("%I64d",&b[i]);
            for(i = 0;i < z ; ++ i)
                scanf("%I64d",&c[i]);
            printf("Case %I64d:\n",++cla);
            LL nu;
            scanf("%I64d",&nu);
            for(i = 0;i < n; ++ i)
                for(j = 0 ;j < m ; ++ j)
                    q[s++] = a[i] + b[j];
            sort(q,q+s);
            while(nu--){
                scanf("%I64d",&t);
                bool vis=false;
                for(i = 0; i < z;++ i){
                    int l = 0,r = s-1;
                    while(r >= l){
                        int mid = (l+r)>>1;
                        if(q[mid] == t-c[i]){
                            vis=true;break;
                        }
                        if(q[mid] < t-c[i]){
                            l = mid + 1;
                        }
                        else{
                            r = mid - 1;
                        }
                    }a
                    if(vis)
                        break;
                }
                if(vis){
                    puts("YES");
                }
                else{
                    puts("NO");
                }
            }
        }
        return 0;
    }

你可能感兴趣的:(二分)