Пример #1
0
 public Node(double value, ACTION action)
 {
     left = right = null;
     key = value;
     number = 0;
     this.action = action;
 }
Пример #2
0
 public Node()
 {
     left = right = null;
     key = -1;
     number = 0;
     action = ACTION.NONE;
 }
Пример #3
0
 public Node(double value)
 {
     left = right = null;
     key = value;
     number = 0;
     action = ACTION.NONE;
 }
Пример #4
0
 public Node(Node left, Node right)
 {
     this.left = left;
     this.right = right;
     key = left.key + right.key;
     number = 0;
     action = ACTION.NONE;
 }
Пример #5
0
 public Node(double key, ACTION action, double number, Node left, Node right)
 {
     this.left = left;
     this.right = right;
     this.key = key;
     this.number = number;
     this.action = action;
 }
Пример #6
0
 public static void Copy(Node from, ref Node to)
 {
     to = from;
 }
Пример #7
0
 private void push(ref Node node, int left, int right)
 {
     if (node != null)
         push(ref node, left, right, ACTION.NONE, 0);
 }
Пример #8
0
        private void push(ref Node node, int left, int right, ACTION action, double value)
        {
            int center = (left + right) / 2;

            if (node.left != null)
                push(ref node.left, left, center, node.action, node.number);

            if (node.right != null)
                push(ref node.right, center + 1, right, node.action, node.number);

            if (node.action == ACTION.LIST)
                node.key = do_action(node.key, action, value);
            else
            {
                double left_value = 0, right_value = 0;

                if (node.left.action == ACTION.UPDATE)
                    left_value = (center - left + 1) * node.left.number;
                else if (node.left.action == ACTION.ADD)
                    left_value = node.left.key + (center - left + 1) * node.left.number;
                else
                    left_value = node.left.key;

                if (node.right.action == ACTION.UPDATE)
                    right_value = (center - left + 1) * node.right.number;
                else if (node.right.action == ACTION.ADD)
                    right_value = node.right.key + (center - left + 1) * node.right.number;
                else
                    right_value = node.right.key;

                node.key = left_value + right_value;

                node.action = action;
                node.number = value;
            }
        }
Пример #9
0
        private void mass_update(ref Node node, int left, int right, int query_left, int query_right, ACTION action, double value)
        {
            if (query_left > query_right)
                return;

            if (left == query_left && right == query_right)
            {
                if (left == right)
                    node.key = do_action(node.key, action, value);
                else if (action == ACTION.UPDATE)
                {
                    clear(ref node);
                    node.action = action;
                    node.number = value;
                }
                else
                {
                    push(ref node, left, right);
                    node.action = action;
                    node.number += value;
                }
            }
            else
            {
                if (node.action == ACTION.ADD || node.action == ACTION.UPDATE)
                    push(ref node, left, right);

                int center = (left + right) / 2;

                mass_update(ref node.left, left, center, query_left, Math.Min(query_right, center), action, value);
                mass_update(ref node.right, center + 1, right, Math.Max(query_left, center + 1), query_right, action, value);

                double left_value = 0, right_value = 0;

                if (node.left.action == ACTION.UPDATE)
                    left_value = (center - left + 1) * node.left.number;
                else if (node.left.action == ACTION.ADD)
                    left_value = node.left.key + (center - left + 1) * node.left.number;
                else
                    left_value = node.left.key;

                if (node.right.action == ACTION.UPDATE)
                    right_value = (center - left + 1) * node.right.number;
                else if (node.right.action == ACTION.ADD)
                    right_value = node.right.key + (center - left + 1) * node.right.number;
                else
                    right_value = node.right.key;

                node.key = left_value + right_value;
            }
        }
Пример #10
0
        private void pointed_update(ref Node node, int left, int right, int position, ACTION action, double value)
        {
            if (left == right)
                node.key = do_action(node.key, action, value);
            else
            {
                int center = (left + right) / 2;

                if (node.action == ACTION.UPDATE)
                    push(ref node, left, right);

                if (position <= center)
                    pointed_update(ref node.left, left, center, position, action, value);
                else
                    pointed_update(ref node.right, center + 1, right, position, action, value);

                node.key = node.left.key + node.right.key;
            }
        }
Пример #11
0
        private double get(Node node, int left, int right, int query_left, int query_right)
        {
            if (query_left > query_right)
                return 0;
            if (left == query_left && right == query_right)
            {
                if (node.action == ACTION.UPDATE || node.action == ACTION.ADD)
                    push(ref node, left, right);

                return node.key;
            }

            int center = (left + right) / 2;

            if (node.action == ACTION.NONE)
                return get(node.left, left, center, query_left, Math.Min(query_right, center))
                        + get(node.right, center + 1, right, Math.Max(query_left, center + 1), query_right);
            else if (node.action == ACTION.ADD || node.action == ACTION.UPDATE)
            {
                push(ref node, left, right);
                return get(node.left, left, center, query_left, Math.Min(query_right, center))
                        + get(node.right, center + 1, right, Math.Max(query_left, center + 1), query_right);
            }
            else
                return node.key;
        }
Пример #12
0
 private Node Copy(Node node)
 {
     if (node == null)
         return null;
     else
         return new Node(node.key, node.action, node.number, Copy(node.left), Copy(node.right));
 }
Пример #13
0
        private void clear(ref Node node)
        {
            if (node.left != null)
                clear(ref node.left);

            if (node.right != null)
                clear(ref node.right);

            if (node.action != ACTION.NONE && node.action != ACTION.LIST)
            {
                node.action = ACTION.NONE;
                node.number = 0;
            }
        }
Пример #14
0
 public ST()
 {
     root = new Node();
     length = 0;
 }
Пример #15
0
        // Constructor
        public ST(params object[] list)
        {
            // Reading an Array
            List<double> temp = new List<double>();

            int len = list.Length;
            for (int i = 0; i < len; i++)
            {
                try
                {
                    double arg0 = Convert.ToDouble(list[i]);
                    temp.Add(arg0);
                }
                catch
                {
                    double[] arg1 = list[i] as double[];
                    if (arg1 != null)
                        temp.AddRange(arg1);
                }
            }

            // Preparing an Segment Tree
            Node node = build(temp, 0, temp.Count - 1);
            root = new Node();
            length = temp.Count;
            Node.Copy(node, ref root);
        }