set:内置平衡树。支持插入删除,动态求前驱后继,最大最小值,二分查找。不支持第k大和排名。
定义:
set<int> S;
set<int> iterator it; //迭代器
常用函数:
S.insert(50); 插入一个元素。自动去重。
S.lower_bound(50); 查找第一个大于等于50的数,返回迭代器,不存在返回end()
S.upper_bound(50); 查找第一个大于50的数,返回迭代器,不存在返回end()
S.erase(it); 删除迭代器指向的元素,一定要保证合法。
最小值S.begin(); 最大值S.rbegin(); 一定要保证存在,否则返回end()。
遍历方法:同vector,nlogn。
vector:向量,实际当不定数组用,功能比较强大,可以用之水过大视野上的普通平衡树一题。
普通平衡树为例:
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; #define prt(a) printf("%d\n", (a)) inline void get(int& r) { char c, b=0; r=0; do {c=getchar(); if (c=='-') b=1;} while(c<'0'||c>'9'); while (c>='0' && c<='9') {r = r*10+c-'0'; c=getchar();} if (b) r=-r; } int N; vector<int> a; vector<int>::iterator p; int main() { a.reserve(100001); get(N); int t, opt; while (N--) { get(opt); get(t); if (opt == 1) a.insert(upper_bound(a.begin(), a.end(), t), t);//插入并保持有序 else if (opt == 2) a.erase(lower_bound(a.begin(), a.end(), t));//删除并保持有序 else if (opt == 3) prt(lower_bound(a.begin(), a.end(), t)-a.begin()+1); else if (opt == 4) prt(a[t-1]); else if (opt == 5) { p = lower_bound(a.begin(), a.end(), t);//前驱 prt(*(--p)); } else prt(*upper_bound(a.begin(), a.end(), t));//后继 } return 0; }可以看出vector还是比较强大的。在不想写平衡树的时候可以简单替代。vector的插入和删除是O(n)的,但是内置有些优化,,所以比较快的。