二分 vs. Hashmap

P2249 【深基13.例1】查找

leave_for @ 2024-01-19 00:49:41

突发奇想

作为一名蒟蒻,我一开始是用递归写的二分,然后果不其然地TLE了\ 懒得再写一遍循环的我突然想到有unordered_map这么个东西,理论单次查询的时间为O(1),比二分的O(log n)还快。于是就有了这么个东西:

#include<iostream>
#include<unordered_map>
using namespace std;
long long read() {
    long long a = 0;
    char c = getchar();
    while (c < '0' || c > '9') c = getchar();
    while (c >= '0' && c <= '9') {
        a = a * 10 + (c - '0');
        c = getchar();
    }
    return a;
}
int main() {
    long long temp=0, q=0, n, m;
    cin >> n >> m;
    unordered_map<long long, int> a;
    for (int i = 0; i < n; i++){
        temp=read();
        if(a[temp]==0) a[temp]=i+1;
    }
    for (int i = 0; i < m; i++) {
        q=read();
        cout << (a[q]==0?-1:a[q]) << ' ';
    }
    return 0;
}

结果很轻松地过了,不比二分慢多少

疑问

可是按理说对于静态有序的数据二分查找会更快,所以到底哪种解法更优呢?


by 崔化博 @ 2024-01-19 01:00:33

如果你自己写一个哈希表的话,那肯定是哈希表O(1)的快。

unordered_map可以被卡成O(n^2)的,而且常数大,一般二分都比他快。 @leave_for


by leave_for @ 2024-01-19 02:30:00

@崔化博 原来是这样。。。 谢谢大佬解答


by Bingxiu @ 2024-01-19 07:35:35

@leave_for unordered_map,理由是时间复杂度更低,但常数大,容易被卡成平方复杂度

比如使用 https://codeforces.com/blog/entry/62393 的方法,有可能能卡掉,不过有可能只能卡成 \Theta(\frac{nmp}{V}),其中 V=10^9,p=107897


by Bingxiu @ 2024-01-19 08:02:23

@leave_for wssb,复杂度应该是 \Theta(\frac{(n+m)V}{p})


|