123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- package main
- import (
- "fmt"
- )
- type node struct {
- l int
- r int
- left *node
- right *node
- val int
- inc int // Lazy
- }
- func (n node) mid() int {
- return n.l + (n.r-n.l)/2
- }
- var tree []node
- var tid int
- func newTree(n int) *node {
- tree = make([]node, 2*n)
- tid = 0
- root := &tree[0]
- root.buildTree(1, n)
- return root
- }
- func (root *node) buildTree(l, r int) {
- root.l = l
- root.r = r
- if l == r {
- return
- }
- tid++
- root.left = &tree[tid]
- tid++
- root.right = &tree[tid]
- m := l + (r-l)/2
- root.left.buildTree(l, m)
- root.right.buildTree(m+1, r)
- }
- func (root *node) update(l, r, val int) {
- if root.l == l && root.r == r {
- root.inc += val
- return
- }
- root.val += (r - l + 1) * val
- if r <= root.mid() {
- root.left.update(l, r, val)
- } else if root.mid()+1 <= l {
- root.right.update(l, r, val)
- } else {
- root.left.update(l, root.mid(), val)
- root.right.update(root.mid()+1, r, val)
- }
- }
- func (root *node) query(l, r int) int {
- if root.l == l && root.r == r {
- return root.val + (r-l+1)*root.inc
- }
- if root.inc != 0 {
- root.val += (root.r - root.l + 1) * root.inc // PushDown
- root.left.update(root.l, root.mid(), root.inc) // !!the RANGE is important
- root.right.update(root.mid()+1, root.r, root.inc)
- }
- root.inc = 0 // Finished update
- if r <= root.mid() {
- return root.left.query(l, r)
- } else if root.mid()+1 <= l {
- return root.right.query(l, r)
- } else {
- return root.left.query(l, root.mid()) + root.right.query(root.mid()+1, r)
- }
- }
- func main() {
- var n int
- fmt.Scan(&n)
- root := newTree(n)
- for i := 1; i <= n; i++ {
- root.update(i, i, i)
- }
- fmt.Println("Sum of 1 ~", n, "is", root.query(1, n))
- var l, r, val int
- fmt.Print("Update(l, r, val): ")
- fmt.Scan(&l, &r, &val)
- root.update(l, r, val)
- fmt.Print("Query(l, r): ")
- fmt.Scan(&l, &r)
- fmt.Println(root.query(l, r))
- }
|