|
@@ -0,0 +1,96 @@
|
|
|
|
+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: ")
|
|
|
|
+ fmt.Scan(&l, &r, &val)
|
|
|
|
+ root.update(l, r, val)
|
|
|
|
+ fmt.Print("Query: ")
|
|
|
|
+ fmt.Scan(&l, &r)
|
|
|
|
+ fmt.Println(root.query(l, r))
|
|
|
|
+}
|