12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- package main
- // SegmentTree ...
- type SegmentTree []int
- // NewSegmentTree ...
- func NewSegmentTree(n int) SegmentTree {
- var st SegmentTree = make([]int, 2*n)
- for i := n; i < 2*n; i++ {
- st[i] = 1
- }
- for i := n - 1; 0 < i; i-- {
- st[i] = st[2*i] + st[2*i+1]
- }
- return st
- }
- // Update ...
- func (st SegmentTree) Update(i, val int) {
- i += len(st) / 2
- st[i] = val
- for i > 1 {
- i /= 2
- st[i] = st[2*i] + st[2*i+1]
- }
- }
- // Search ...
- func (st SegmentTree) Search(beg, val int) (end int) {
- val %= st[1] // Deal with the loop
- if val == 0 { // If val is zero, set val to st[1]
- val = st[1]
- }
- n := len(st) / 2
- slotCnt := st.Count(beg, n)
- if slotCnt < val { // If slot cnt is not enough, start from the begining
- val -= slotCnt
- beg = 0
- }
- beg, end = beg+n, beg+n
- for st[end] < val {
- if end%2 == 1 { // If is right child, move to left child
- val -= st[end]
- end++
- }
- end /= 2
- } // Find the interval that contains end from bottom to top
- for end < n { // While end is not leaf
- lchild, rchild := end*2, end*2+1
- if st[lchild] < val {
- val -= st[lchild]
- end = rchild // Find in right tree
- } else { // st[lchild] == val
- end = lchild // Find in left tree
- }
- }
- return end - n
- }
- // Count ...
- func (st SegmentTree) Count(left, right int) (sum int) {
- n := len(st) / 2
- left, right = left+n, right+n
- for left < right {
- if left%2 == 1 {
- sum += st[left]
- left++
- }
- if right%2 == 1 { // right is not included, so --
- right--
- sum += st[right]
- }
- left, right = left/2, right/2
- }
- return
- }
|