zoukankan      html  css  js  c++  java
  • hdu_4334,线性查找的学习

    http://acm.hdu.edu.cn/showproblem.php?pid=4334

    这题开始做的时候,不是O(n^2)*O(logn^3) MLE就是O(n^3)*O(logn^2) TLE了

    后来看解题报告都没看懂

    幽幽子大神给我讲了下,真的是恍然大悟啊

    while(j < cnt1 && k >= 0){
         if(f[j] + g[k] == -tmp){
         flag = 1;
            break;
         }
         if(f[j] + g[k] < 0 - tmp) j ++;
            else k --;
    }

    对于这一段,开始用最小的加最大的,如果和小于要查找的话,那么说明大的不够用,小的就加,即j++

    反之就 k--了

    给跪子orz 

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define ll __int64
    
    ll a[210];
    ll b[210];
    ll c[210];
    ll f[202*202];
    ll g[202*202];
    int n;
    int main(){
        int tcase;
        scanf("%d", &tcase);
        while(tcase --){
            scanf("%d", &n);
            memset(f, 0, sizeof f);
            memset(g, 0, sizeof g);
            int cnt1 = 0;
            int cnt2 = 0;
            for(int i = 0; i < n; i ++) scanf("%I64d", a + i);
            for(int i = 0; i < n; i ++) scanf("%I64d", b + i);
            for(int i = 0; i < n; i ++) scanf("%I64d", c + i);
            for(int i = 0; i < n; i ++){
                for(int j = 0; j < n; j ++){
                    f[cnt1++] = a[i] + b[j];
                }
            }
            for(int i = 0; i < n; i ++) scanf("%I64d", a + i);
            for(int i = 0; i < n; i ++){
                for(int j = 0; j < n; j ++){
                    g[cnt2++] = a[i] + c[j];
                }
            }
            for(int i = 0; i < n; i ++) scanf("%I64d", c + i);
    
            sort(f, f + cnt1);
            sort(g, g + cnt2);
            sort(c, c + n);
    
            int flag = 0;
            for(int i = 0; i < n; i ++){
                ll tmp = c[i];
                int j = 0;
                int k = cnt2 - 1;
                while(j < cnt1 && k >= 0){
                    if(f[j] + g[k] == -tmp){
                        flag = 1;
                        break;
                    }
                    if(f[j] + g[k] < 0 - tmp) j ++;
                    else k --;
                }
            }
            /*
            for(int i = 0; i < cnt1; i ++){
                for(int j = 0; j < n; j ++){
                    ll tmp = 0 - f[i] - c[j];
                    if(tmp < g[0] || tmp > g[cnt2-1])continue;
                    int l = 0, r = cnt2-1;
                    int fl = 0;
                    while(l <= r){
                        int mid = l + r >> 1;
                        if(g[mid] == tmp){
                            fl = 1;
                            break;
                        }
                        if(tmp < g[mid])
                            r = mid-1;
                        else if(tmp > g[mid])
                            l = mid+1;
                    }
                    if(fl){
                        flag = 1;
                        break;
                    }
                }
                if(flag) break;
            }
            */
            if(flag)
              puts("Yes");
            else
              puts("No");
        }
        return 0;
    }
  • 相关阅读:
    【BZOJ3218】 a+b Problem
    【BZOJ3993】 星际战争
    【BZOJ3991】 寻宝游戏
    【BZOJ2959】长跑 (LCT+并查集)
    NOIP2017记
    【CF 678F】Lena and Queries
    【Learning】多项式乘法与快速傅里叶变换(FFT)
    Subsequence Count (线段树)
    【留言板】
    【bzoj 4173】数学
  • 原文地址:https://www.cnblogs.com/louzhang/p/2620588.html
Copyright © 2011-2022 走看看