张桄玮
郑州一中(Legacy)
理解优先队列的一种实现方法: 二叉堆
使用STL
操作:
是一棵完全二叉树(最后一层从左往右依次排列中间不会空缺)
小根堆的情形:
既然知道了最多有2个节点, 就可以做一个简单的映射
好处: 简单, 紧凑; 坏处: 稀疏的时候占据大量无用空间
down(x) 把 \(x\)
往下调整: 不停地找到根左右之间的最小值, 把它与之交换up(x) 把 \(x\)
往上调整: 不停地与父亲节点比较, 如果父亲节点比较大,
就与父亲节点交换void push_up(int i, int val) {
while (i > 1 && val < heap[i / 2]) {heap[i] = heap[i / 2]; i /= 2;}heap[i] = val;
}
void push_down(int i, int val) {
int ch = i * 2;
while (ch <= size) {
if (ch < size && heap[ch + 1] < heap[ch]) ch++;if (val <= heap[ch]) break;
heap[i] = heap[ch];i = ch;ch *= 2;
}
heap[i] = val;
}插入: 先放到最底下, 然后往上浮动
把根删了, 然后找一个节点顶上来, 往下移动到合适的位置.
heap[k]=heap[size];size--;down(k)或up(k);heap[k]=x;down(k)或up(k);思路: 开一个大根堆和小根堆
然后输出堆顶的元素即可.
题目大意
思考:
\[ \begin{aligned} A[1]+B[1] &\leq A[1]+B[2]&\leq &\cdots &\leq A[1]+B[N] \\ A[2]+B[1] &\leq A[2]+B[2]&\leq &\cdots &\leq A[2]+B[N] \\ && \vdots\\ A[N]+B[1] &\leq A[N]+B[2]&\leq &\cdots &\leq A[N]+B[N] \\ \end{aligned} \]
STL: 构建程序能够普遍受惠的标准库
标准库函数比大家多考虑的事情:
vector<pair<int, int> >中的空格了!auto代替
auto a=42; // a is of type intint vals[]{1,2,3};std::vector<int> v{1,2,3};range-based for循环
for(decl:coll){ stmt }
pair 有序对std::pair<TypA, TypB> p;p.first; 第二个元素:
p.second.p=make_pair(val1, val2);std::tie(ra, rb)=p.tuple 不定数的值组std命名空间tuple<Typ_1, Typ_2, ..., Typ_n> t;Typ_i s = get<i>(t);make_tuple("jyy", "NJU", 2024);get<i> 的 \(i\) 要在编译期就决定tuple里面写值就更复杂了. 直接摆烂!)struct说
容器有三大类别:
序列式容器 – 链表/数组
array, vector, deque, list, forward_list关联式容器 – 二叉树
set, multiset, map, multimap无序容器 – Hash表
unordered_map,unordered_setvectorvector<Type> vec;vec.push_back(elem);vec[i];vec.size();实现细节: 当发现不够的时候, 开一个更大的空间把数组的内容搬过去
deque喜提 push_front: 往前面插入元素
list一些操作
set (多重集合multiset)依照他们的 “顺序” 排列(严格偏序)
x<y, 一定没有y<xx<y, y<z \(\to\)
x<zx<x 永远不成立a==b, b==c \(\to\)
a==c操作
map