lower_bound不能乱用。。血的教训!

之前写了一题本应用Splay维护单点修改,查询最小的不小于它的那个数排在哪个位置。

我偷了下懒,用STL做。。。结果TLE了。。。

我们使用这段短短的代码进行测试:

#include <cstdio>
#include <set>

using namespace std;

set <int> g;
int n;

int main() {
    freopen("s.in","r",stdin);
    freopen("s.out","w",stdout);
    scanf("%d", &n);
    g.clear();
    for (int i=1;i<=n;i++) g.insert(i);
    for (int i=1;i<=n;i++) printf("%d
", *lower_bound(g.begin(), g.end(), i));
    return 0;
}

我们尝试n = 10000的测试数据,用时2.71s。

我们尝试n = 50000的测试数据,用时64.25s。

我们去掉lower_bound试试?

尝试n = 10000的测试数据,用时0.01s。

尝试n = 50000的测试数据,用时0.1s。

看来在STL set里用lower_bound效率是n^2的。

[Aug 24, 2014 Update]

我意外地发现set里也有一个lower_bound函数,于是去试了一下。效率很高耶。

//
//  main.cpp
//  test
//
//  Created by Africamonkey on 8/24/14.
//  Copyright (c) 2014 Africamonkey. All rights reserved.
//

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <set>

using namespace std;

#define N 100000

set < int > cset;

int a[N+1];

int main(int argc, const char * argv[])
{
    srand((unsigned int) time(0));
    freopen("std.out","w",stdout);
    for (int i=1;i<=N;i++) a[i] = i;
    for (int i=1;i<=N*5;i++) {
        int t, x = rand() % N + 1, y = rand() % N + 1;
        t = a[x], a[x] = a[y], a[y] = t;
    }
    for (int i=1;i<=N;i++) cset.insert(a[i]);
    for (int i=1;i<=N*5;i++) {
        int t, x = rand() % N + 1, y = rand() % N + 1;
        t = a[x], a[x] = a[y], a[y] = t;
    }
    for (int i=1;i<=N;i++) //printf("%d
", (*lower_bound(cset.begin(), cset.end(), i)));
        printf("%d
", (*cset.lower_bound(a[i])));
    for (int i=1;i<=N*5;i++) {
        int t, x = rand() % N + 1, y = rand() % N + 1;
        t = a[x], a[x] = a[y], a[y] = t;
    }
    for (int i=1;i<=N;i++) {
        cset.erase(a[i]);
    }
    return 0;
}

我拿这段代码去跑,瞬间就出来了。

原文地址:https://www.cnblogs.com/africamonkey/p/3921220.html