Weighted Segment Tree in Fenwick Tree
The problem of Static Range k-th Smallest Value (POJ 2104 K-th Number) can be solved using a Weighted Segment Tree in \(O(n\log n)\) time complexity.
What if the range becomes dynamic? That is, if we also need to support an operation: modifying the value at a single position, what should we do?
Example Problem Second-Order Balanced Tree (Tree of Trees)
Maintain an ordered sequence, which requires the following operations:
- Query the rank of \(x\) within the interval;
- Query the value with rank \(k\) within the interval;
- Modify the value at a certain position;
- Query the predecessor of \(x\) within the interval (predecessor defined as the largest number less than \(x\));
- Query the successor of \(x\) within the interval (successor defined as the smallest number greater than \(x\)).
Example Problem Luogu P2617 Dynamic Rankings
Given a sequence \(a_1,a_2 \dots a_n\) containing \(n\) numbers, support two types of operations:
Q l r kmeans query the \(k\)-th smallest number with indices in the interval \([l,r]\).C x ymeans change \(a_x\) to \(y\).
If we use the method discussed in Segment Tree of Balanced Trees, i.e., for each node of the segment tree, maintain a balanced tree for the interval it represents, and then use binary search to find the \(k\)-th smallest value. Since each query operation covers multiple intervals, i.e., multiple nodes, but balanced trees cannot search multiple values simultaneously, the time complexity is \(O(n\log^3 n)\), which is not optimal.
The optimization idea is to combine the binary search for the answer with the operation of querying the count of numbers less than a certain value, using a Segment Tree of Dynamically Allocated Weighted Segment Trees. Since all segment trees have the same structure, we can perform segment tree binary search on multiple trees simultaneously.
During a modification operation, we first traverse down the segment tree to the point being modified, delete the old value from the dynamically allocated weighted segment trees pointed to by the nodes along the path, and then insert the new value. This involves \(O(\log n)\) segment tree nodes, and each modification in the dynamically allocated weighted segment tree is \(O(\log n)\), so the time complexity of a modification operation is \(O(\log^2 n)\).
When querying for an answer, we first collect all the segment tree nodes that cover the interval, then use a method similar to the static range \(k\)-th smallest value to move these nodes together to the left child or right child. If the total value stored in the left children of all these nodes is greater than or equal to \(k\), we move left; otherwise, we move right. Since at most \(O(\log n)\) nodes are covered, at most that many nodes move down at each step, resulting in a time complexity of \(O(\log^2 n)\).
Due to the large constant factor of segment trees, in practice, a Fenwick Tree with a smaller constant and more convenient handling of prefix sums is often used. Additionally, the space complexity is \(O(n\log^2 n)\), so pay attention to space limits when using it.
Here is one code implementation:
Implementation
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | |
本页面最近更新:,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:OI-wiki
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用