码迷,mamicode.com
首页 > 其他好文 > 详细

线段树

时间:2014-09-18 18:09:24      阅读:278      评论:0      收藏:0      [点我收藏+]

标签:des   blog   os   ar   for   div   sp   log   on   

 

object IntervalTree1 extends App
{
    val score = Array(1, 2, 3, 4, 5)

    val commands = Array(
        "Q 1 5", "U 3 6", "Q 3 4",
        "Q 4 5", "U 2 9", "Q 1 5"
    )


    val (n, m) = (5, 6)
    val iTree = new IntervalTree

    var root: Tree = _
    root = iTree.build(1, n)
    //iTree.printTree(root)

    commands.foreach( cmd => {
        val tokens = cmd.split(" ")
        val (c, a, b) = (tokens(0), tokens(1).toInt, tokens(2).toInt)

        c match {
            case "Q" => println(iTree.query(root, a, b))
            case "U" => {score(a) = b; iTree.update(root, a, b)}
        }
    })


    class Tree
    {
        var l: Tree = null
        var r: Tree = null
        var lv = 0
        var rv = 0
        var maxscore = 0
    }

    class IntervalTree
    {
        var pos = 0
        var nodes = Array.fill(400010)(new Tree())


        def build(left: Int, right: Int): Tree =
        {
            val node = nodes(pos); pos += 1
            node.lv = left; node.rv = right;

            if (left == right) {
                node.maxscore = Math.max(score(left - 1), score(right - 1))
                node
            }
            else {
                val mid = (left + right) >> 1
                node.l = build(left, mid)
                node.r = build(mid + 1, right)
                node.maxscore = Math.max(node.l.maxscore, node.r.maxscore)
            }
            node
        }

        def query(root: Tree, left: Int, right: Int): Int =
        {
            if (left == root.lv && right == root.rv) return root.maxscore

            val mid = (root.lv + root.rv) >> 1
            mid match {
                case m if (right <= m) => query(root.l, left, right)
                case m if (left > m) => query(root.r, left, right)
                case _ => Math.max(query(root.l, left, mid), query(root.r, mid + 1, right))
            }
        }

        def update(root: Tree, value: Int, newValue: Int): Int =
        {
            val mid = (root.lv + root.rv) >> 1
            if (value == root.lv &&  value == root.rv) {
                root.maxscore = newValue
                return root.maxscore
            }

            val ret = mid match {
                case m if value <= m => update(root.l, value,  newValue)
                case m if value > m => update(root.r, value, newValue)
            }

            root.maxscore = Math.max(root.maxscore, ret)
            root.maxscore
        }

        def printTree(node: Tree)
        {
            if (node != null) {
                println(s"[${node.lv},${node.rv}]")
                printTree(node.l)
                printTree(node.r)
            }
        }
    }
}

  

线段树

标签:des   blog   os   ar   for   div   sp   log   on   

原文地址:http://www.cnblogs.com/rilley/p/3979568.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!