using System; using System.Collections.Generic; class SegmentTree { const int MAXSIZE = 1000; const long INF = long.MaxValue; static long[] tree = new long[MAXSIZE]; static long[] lazy = new long[MAXSIZE]; // Build our segment tree static void BuildTree(long[] arr, int arrSize) { Stack<(long, long, long)> st = new Stack<(long, long, long)>(); st.Push((1, 0, arrSize - 1)); while (st.Count > 0) { (long currNode, long curra, long currb) = st.Pop(); if (curra == INF && currb == INF) tree[currNode] = tree[currNode * 2] + tree[currNode * 2 + 1]; else if (curra == currb) tree[currNode] = arr[curra]; else { st.Push((currNode, INF, INF)); long mid = (curra + currb) / 2; st.Push((currNode * 2, curra, mid)); st.Push((currNode * 2 + 1, mid + 1, currb)); } } } // A utility function that propagates // updates lazily down the tree static void PushDown(long node, long a, long b) { if (lazy[node] != 0) { tree[node] += lazy[node] * (b - a + 1); if (a != b) { lazy[2 * node] += lazy[node]; lazy[2 * node + 1] += lazy[node]; } lazy[node] = 0; } } // Iterative Range_Update function to // add val to all elements in the // range i-j (inclusive) static void UpdateTree(int arrSize, long i, long j, long val) { Stack<(long, long, long)> st = new Stack<(long, long, long)>(); st.Push((1, 0, arrSize - 1)); while (st.Count > 0) { (long currNode, long curra, long currb) = st.Pop(); if (curra == INF && currb == INF) tree[currNode] = tree[currNode * 2] + tree[currNode * 2 + 1]; else { PushDown(currNode, curra, currb); if (curra > currb || curra > j || currb < i) continue; else if (curra >= i && currb <= j) { tree[currNode] += val * (currb - curra + 1); if (curra != currb) { lazy[currNode * 2] += val; lazy[currNode * 2 + 1] += val; } } else { st.Push((currNode, INF, INF)); long mid = (curra + currb) / 2; st.Push((currNode * 2, curra, mid)); st.Push((currNode * 2 + 1, mid + 1, currb)); } } } } // A function that finds the sum of // all elements in the range i-j static long Query(int arrSize, long i, long j) { Stack<(long, long, long)> st = new Stack<(long, long, long)>(); st.Push((1, 0, arrSize - 1)); long result = 0; while (st.Count > 0) { (long currNode, long curra, long currb) = st.Pop(); PushDown(currNode, curra, currb); if (curra > currb || curra > j || currb < i) continue; else if (curra >= i && currb <= j) result += tree[currNode]; else { long mid = (curra + currb) / 2; st.Push((currNode * 2, curra, mid)); st.Push((currNode * 2 + 1, mid + 1, currb)); } } return result; } // Driver Code static void Main() { // Initialize our trees with 0 Array.Clear(tree, 0, MAXSIZE); Array.Clear(lazy, 0, MAXSIZE); long[] arr = { 1, 3, 5, 7, 9, 11 }; int n = arr.Length; // Build segment tree from given array BuildTree(arr, n); // Print sum of values in array // from index 1 to 3 Console.WriteLine("Sum of values in given range = " + Query(n, 1, 3)); // Add 10 to all nodes at indexes // from 1 to 5 UpdateTree(n, 1, 5, 10); // Find sum after the value is updated Console.WriteLine("Updated sum of values in given range = " + Query(n, 1, 3)); } }