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\n", *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\n", (*lower_bound(cset.begin(), cset.end(), i))); printf("%d\n", (*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; }
我拿这段代码去跑,瞬间就出来了。