Block List

A block list roughly looks like this...
It's not hard to see that a block list is essentially a linked list, where each node points to an array.
We divide the original array of length \(n\) into \(\sqrt{n}\) nodes, each node corresponding to an array of size \(\sqrt{n}\).
Thus, we define the structure as follows, with the code shown below.
Here, sqn represents sqrt(n), i.e., \(\sqrt{n}\), and pb stands for push_back, meaning adding an element to this node.
Implementation
1 2 3 4 5 6 7 8 9 | |
A block list should support at least: splitting, insertion, and searching.
What is splitting? Splitting is dividing a node into two smaller nodes to ensure each node's size remains close to \(\sqrt{n}\) (otherwise, it might degenerate into a regular array). When a node's size exceeds \(2 \times \sqrt{n}\), a split operation is performed.
How is the split operation done? First, create a new node, then copy the last \(\sqrt{n}\) values from the node being split to the new node. Next, delete the last \(\sqrt{n}\) values from the node being split (size--). Finally, insert the new node after the node being split.
All operations on a block list have a complexity of \(\sqrt{n}\).
One more thing to mention. As elements are inserted (or deleted), \(n\) changes, and so does \(\sqrt{n}\). This means the block size would change. Do we really need to maintain the block size every time?
Actually, no. We can set \(\sqrt{n}\) as a fixed value. For example, if the problem's range is \(10^6\), then set \(\sqrt{n}\) as a constant of size \(10^3\), and there's no need to change it.
1 | |
rope in STL
Import
The rope in STL also serves as a block list. It is implemented using a persistent balanced tree and supports random access, insertion, and deletion of elements.
Since rope is not truly implemented as a block list, its time complexity is not equivalent to that of a block list but rather to that of a persistent balanced tree (i.e., \(O(\log n)\)).
It can be imported as follows:
1 2 | |
About Library Functions Starting with Double Underscores
In OI, the permissibility of using library functions starting with double underscores was once uncertain. The Supplementary Explanation on Programming Language Usage Restrictions in NOI Series Activities released by CCF in 2021 states: "The use of library functions or macros starting with an underscore is allowed, except for those with explicitly prohibited operations." Therefore, rope can currently be used normally in OI.
Basic Operations
| Operation | Effect |
|---|---|
rope <int > a |
Initialize a rope (similar to containers like vector) |
a.push_back(x) |
Add element x to the end of a |
a.insert(pos, x) |
Insert element x at the pos-th position of a |
a.erase(pos, x) |
Delete x elements starting from the pos-th position of a |
a.at(x) or a[x] |
Access the x-th element of a |
a.length() or a.size() |
Get the size of a |
Example Problem
Solution: A very simple template problem. The code is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | |
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用