diff --git a/AreaOfRectangle.java b/AreaOfRectangle.java new file mode 100644 index 0000000..12f83ac --- /dev/null +++ b/AreaOfRectangle.java @@ -0,0 +1,38 @@ +package SegTree; + +public class AreaOfRectangle { + public int mod = 1000000007; + + public int rectangleArea(int[][] rectangles) { + boolean[][] arr = new boolean[201][201]; + + for (int[] rectangle : rectangles) { + makeRectangle(arr, rectangle); + } + + long ans = 0; + for (boolean[] ar : arr) { + for (boolean b : ar) { + if (b) + ++ans; + } + } + return (int) (ans % mod); + } + + private void makeRectangle(boolean[][] arr, int[] rectangle) { + int x1 = rectangle[0], y1 = rectangle[1], x2 = rectangle[2], y2 = rectangle[3]; + + for (int i = x1; i <= x2; ++i) { + for (int j = y1; j <= y2; ++j) { + arr[i][j] = true; + } + } + } + + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +} diff --git a/NumMatrix.java b/NumMatrix.java new file mode 100644 index 0000000..21dbc07 --- /dev/null +++ b/NumMatrix.java @@ -0,0 +1,59 @@ +package SegTree; + +public class NumMatrix { + + public int[][] ba; + public int[][] sa; + + public NumMatrix(int[][] matrix) { + int ln = findLog(matrix[0].length); + sa = new int[matrix.length][1 << (ln + 1)]; + ba = matrix; + build(0, 0, matrix[0].length - 1); + } + + public int findLog(int n) { + int log = 0; + + while (n > 0) { + ++log; + n = n >> 1; + } + return log; + } + + public void build(int si, int ss, int se) { + if (se == ss) { + for (int i = 0; i < ba.length; ++i) { + sa[i][si] = ba[i][ss]; + } + return; + } + + int mid = (ss + se) / 2; + build(si * 2 + 1, ss, mid); + build(si * 2 + 2, mid + 1, se); + + for (int i = 0; i < ba.length; ++i) + sa[i][si] = sa[i][si * 2 + 1] + sa[i][si * 2 + 2]; + } + + public int query(int si, int qrow1, int qcol1, int qrow2, int qcol2, int col1, int col2) { + int ans = 0; + if (col1 >= qcol1 && col2 <= qcol2) { + for (int i = qrow1; i <= qrow2; ++i) { + ans += sa[i][si]; + } + } else if (col1 > qcol2 || col2 < qcol1) { + } else { + int mid = (col1 + col2) / 2; + ans = query(si * 2 + 1, qrow1, qcol1, qrow2, qcol2, col1, mid) + + query(si * 2 + 2, qrow1, qcol1, qrow2, qcol2, mid + 1, col2); + } + return ans; + } + + public int sumRegion(int row1, int col1, int row2, int col2) { + return query(0, row1, col1, row2, col2, 0, ba[0].length-1); + } +} \ No newline at end of file diff --git a/lazy.java b/lazy.java new file mode 100644 index 0000000..caaee5e --- /dev/null +++ b/lazy.java @@ -0,0 +1,154 @@ +package SegTree; + +public class lazy { + + public static int[] ba; + public static int[] sa; + public static int[] la; + + public static int getLog(int n) { + int log = 0; + while (n > 0) { + ++log; + n = n >> 1; + } + + return log; + } + + public static void make(int[] nums) { + int size = (1 << (getLog(nums.length) + 1)); + ba = nums; + sa = new int[size]; + la = new int[size]; + build(0, 0, nums.length - 1); + } + + private static void build(int si, int ss, int se) { + if (ss == se) { + sa[si] = ba[ss]; + return; + } + + int mid = (ss + se) / 2; + + build(2 * si + 1, ss, mid); + build(2 * si + 2, mid + 1, se); + + sa[si] = Math.max(sa[2 * si + 1], sa[2 * si + 2]); + } + + public static int query(int qs, int qe) { + return query(0, 0, ba.length, qs, qe); + } + + private static int query(int si, int ss, int se, int qs, int qe) { + if (ss > qe || qs > se) { + return Integer.MIN_VALUE; + } else if (ss >= qs && se <= qe) { + return sa[si]; + } else { + int mid = (ss + se) / 2; + return Math.max(query(si * 2 + 1, ss, mid, qs, qe), query(si * 2 + 2, mid + 1, se, qs, qe)); + } + } + + public static void update(int index, int val) { + update(0, index, val, 0, ba.length - 1); + } + + public static void update(int vidx, int index, int val, int ss, int se) { + if (ss == se) { + sa[vidx] = val; + ba[se] = val; + return; + } + int mid = (ss + se) / 2; + + if (index <= mid) { + update(vidx * 2 + 1, index, val, ss, mid); + } else { + update(vidx * 2 + 2, index, val, mid + 1, se); + } + + sa[vidx] = Math.max(sa[vidx * 2 + 1], sa[vidx * 2 + 2]); + } + + public static void lazy_update(int delta, int us, int ue) { + lazy_update(0, 0, ba.length - 1, us, ue, delta); + } + + private static void lazy_update(int si, int ss, int se, int us, int ue, int delta) { + + if (la[si] != 0) { + + sa[si] += la[si]; + if (ss != se) { + la[si * 2 + 1] += la[si]; + la[si * 2 + 2] += la[si]; + } + la[si] = 0; + } + + if (ss > ue || se < us) { + return; + } else if (ss >= us && se <= ue) { + sa[si] += delta; + + if (se != ss) { + la[2 * si + 1] += delta; + la[2 * si + 2] += delta; + } + return; + } + + int mid = (ss + se) / 2; + + lazy_update(si * 2 + 1, ss, mid, us, ue, delta); + lazy_update(si * 2 + 2, mid + 1, se, us, ue, delta); + + sa[si] = Math.max(sa[si * 2 + 1], sa[si * 2 + 2]); + } + + public static int lazy_query(int qs, int qe) { + return lazy_query(0, 0, ba.length, qs, qe); + } + + private static int lazy_query(int si, int ss, int se, int qs, int qe) { + + if (la[si] != 0) { + sa[si] += sa[si]; + + if (ss != se) { + la[2 * si + 1] += la[si]; + la[2 * si + 2] += la[si]; + } + la[si] = 0; + } + + if (se < qs || qe < ss) { + return Integer.MIN_VALUE; + } else if (ss >= qs && se <= qe) { + return sa[si]; + } + int mid = (ss + se) / 2; + return Math.max(lazy_query(si * 2 + 1, ss, mid, qs, qe), lazy_query(si * 2 + 2, mid + 1, se, qs, qe)); + + } + + public static void main(String[] args) { + int[] nums = { 0,1,2,3,4,5,6,7,8,9,10 }; + make(nums); +// System.out.println(query(0, 3)); +// update(2, 9999); +// System.out.println(query(0, 3)); + + lazy_update(10, 0, 3); + System.out.println(lazy_query(0, 3)); + lazy_update(-10, 3, 3); + System.out.println(lazy_query(0, 3)); + + + } + +} diff --git a/lazySegmentTree.java b/lazySegmentTree.java new file mode 100644 index 0000000..82b53f9 --- /dev/null +++ b/lazySegmentTree.java @@ -0,0 +1,204 @@ +package SegTree; + +//Java program to demonstrate lazy propagation in segment tree +class lazySegmentTree { + final int MAX = 1000; // Max tree size + int tree[] = new int[MAX]; // To store segment tree + int lazy[] = new int[MAX]; // To store pending updates + + /* + * si -> index of current node in segment tree ss and se -> Starting and ending + * indexes of elements for which current nodes stores sum. us and eu -> starting + * and ending indexes of update query ue -> ending index of update query diff -> + * which we need to add in the range us to ue + */ + void updateRangeUtil(int si, int ss, int se, int us, int ue, int diff) { + // If lazy value is non-zero for current node of segment + // tree, then there are some pending updates. So we need + // to make sure that the pending updates are done before + // making new updates. Because this value may be used by + // parent after recursive calls (See last line of this + // function) + if (lazy[si] != 0) { + // Make pending updates using value stored in lazy + // nodes + tree[si] += (se - ss + 1) * lazy[si]; + + // checking if it is not leaf node because if + // it is leaf node then we cannot go further + if (ss != se) { + // We can postpone updating children we don't + // need their new values now. + // Since we are not yet updating children of si, + // we need to set lazy flags for the children + lazy[si * 2 + 1] += lazy[si]; + lazy[si * 2 + 2] += lazy[si]; + } + + // Set the lazy value for current node as 0 as it + // has been updated + lazy[si] = 0; + } + + // out of range + if (ss > se || ss > ue || se < us) + return; + + // Current segment is fully in range + if (ss >= us && se <= ue) { + // Add the difference to current node + tree[si] += (se - ss + 1) * diff; + + // same logic for checking leaf node or not + if (ss != se) { + // This is where we store values in lazy nodes, + // rather than updating the segment tree itelf + // Since we don't need these updated values now + // we postpone updates by storing values in lazy[] + lazy[si * 2 + 1] += diff; + lazy[si * 2 + 2] += diff; + } + return; + } + + // If not completely in rang, but overlaps, recur for + // children, + int mid = (ss + se) / 2; + updateRangeUtil(si * 2 + 1, ss, mid, us, ue, diff); + updateRangeUtil(si * 2 + 2, mid + 1, se, us, ue, diff); + + // And use the result of children calls to update this + // node + tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; + } + + // Function to update a range of values in segment + // tree + /* + * us and eu -> starting and ending indexes of update query ue -> ending index + * of update query diff -> which we need to add in the range us to ue + */ + void updateRange(int n, int us, int ue, int diff) { + updateRangeUtil(0, 0, n - 1, us, ue, diff); + } + + /* + * A recursive function to get the sum of values in given range of the array. + * The following are parameters for this function. si --> Index of current node + * in the segment tree. Initially 0 is passed as root is always at' index 0 ss & + * se --> Starting and ending indexes of the segment represented by current + * node, i.e., tree[si] qs & qe --> Starting and ending indexes of query range + */ + int getSumUtil(int ss, int se, int qs, int qe, int si) { + // If lazy flag is set for current node of segment tree, + // then there are some pending updates. So we need to + // make sure that the pending updates are done before + // processing the sub sum query + if (lazy[si] != 0) { + // Make pending updates to this node. Note that this + // node represents sum of elements in arr[ss..se] and + // all these elements must be increased by lazy[si] + tree[si] += (se - ss + 1) * lazy[si]; + + // checking if it is not leaf node because if + // it is leaf node then we cannot go further + if (ss != se) { + // Since we are not yet updating children os si, + // we need to set lazy values for the children + lazy[si * 2 + 1] += lazy[si]; + lazy[si * 2 + 2] += lazy[si]; + } + + // unset the lazy value for current node as it has + // been updated + lazy[si] = 0; + } + + // Out of range + if (ss > se || ss > qe || se < qs) + return 0; + + // At this point sure, pending lazy updates are done + // for current node. So we can return value (same as + // was for query in our previous post) + + // If this segment lies in range + if (ss >= qs && se <= qe) + return tree[si]; + + // If a part of this segment overlaps with the given + // range + int mid = (ss + se) / 2; + return getSumUtil(ss, mid, qs, qe, 2 * si + 1) + getSumUtil(mid + 1, se, qs, qe, 2 * si + 2); + } + + // Return sum of elements in range from index qs (query + // start) to qe (query end). It mainly uses getSumUtil() + int getSum(int n, int qs, int qe) { + // Check for erroneous input values + if (qs < 0 || qe > n - 1 || qs > qe) { + System.out.println("Invalid Input"); + return -1; + } + + return getSumUtil(0, n - 1, qs, qe, 0); + } + + /* + * A recursive function that constructs Segment Tree for array[ss..se]. si is + * index of current node in segment tree st. + */ + void constructSTUtil(int arr[], int ss, int se, int si) { + // out of range as ss can never be greater than se + if (ss > se) + return; + + /* + * If there is one element in array, store it in current node of segment tree + * and return + */ + if (ss == se) { + tree[si] = arr[ss]; + return; + } + + /* + * If there are more than one elements, then recur for left and right subtrees + * and store the sum of values in this node + */ + int mid = (ss + se) / 2; + constructSTUtil(arr, ss, mid, si * 2 + 1); + constructSTUtil(arr, mid + 1, se, si * 2 + 2); + + tree[si] = tree[si * 2 + 1] + tree[si * 2 + 2]; + } + + /* + * Function to construct segment tree from given array. This function allocates + * memory for segment tree and calls constructSTUtil() to fill the allocated + * memory + */ + void constructST(int arr[], int n) { + // Fill the allocated memory st + constructSTUtil(arr, 0, n - 1, 0); + } + + // Driver program to test above functions + public static void main(String args[]) { + int arr[] = { 1, 3, 5, 7, 9, 11 }; + int n = arr.length; + lazySegmentTree tree = new lazySegmentTree(); + + // Build segment tree from given array + tree.constructST(arr, n); + + // Print sum of values in array from index 1 to 3 + System.out.println("Sum of values in given range = " + tree.getSum(n, 1, 3)); + + // Add 10 to all nodes at indexes from 1 to 5. + tree.updateRange(n, 1, 5, 10); + + // Find sum after the value is updated + System.out.println("Updated sum of values in given range = " + tree.getSum(n, 1, 3)); + } +} \ No newline at end of file diff --git a/segTree2D.java b/segTree2D.java new file mode 100644 index 0000000..b46e773 --- /dev/null +++ b/segTree2D.java @@ -0,0 +1,21 @@ +package SegTree; + +public class segTree2D { + + public static void main(String[] args) { + + int[][] matrix = { + { 3, 0, 1, 4, 2 }, + { 5, 6, 3, 2, 1 }, + { 1, 2, 0, 1, 5 }, + { 4,1, 0, 1, 7 }, + { 1, 0, 3, 0, 5 } }; + NumMatrix obj = new NumMatrix(matrix); + + System.out.println(obj.sumRegion(2, 1, 4, 3)); + System.out.println(obj.sumRegion(1, 1, 2, 2)); + System.out.println(obj.sumRegion(1, 1, 2, 4)); + + } + +} diff --git a/stree.java b/stree.java new file mode 100644 index 0000000..74fa31d --- /dev/null +++ b/stree.java @@ -0,0 +1,50 @@ +package SegTree; + +public class stree { + public static int ba[], sa[]; + + public static int getLog(int n) { + int log = 0; + while ((1 << log) < n) { + log++; + } + + return log; + } + + public static void build(int in, int ss, int se) { + if (ss == se) { + sa[in] = ba[ss]; + return; + } + + int mid = (ss + se) / 2; + + build(2 * in + 1, ss, mid); + build(2 * in + 2, mid + 1, se); + + sa[in] = Math.max(sa[2 * in + 1], sa[2 * in + 2]); + } + + public static int query(int index, int qs, int qe, int ss, int se) { + if (qs <= ss && qe >= se) { + return sa[index]; + } else if (ss > qe || se < qs) { + return Integer.MIN_VALUE; + } else { + int mid = (ss + se) / 2; + return Math.max(query(index * 2 + 1, qs, qe, ss, mid), query(index * 2 + 2, qs, qe, mid + 1, se)); + } + } + + public static void main(String[] args) { + ba = new int[] { 20, 22, 11, 55, -567, 88, 55, 7, 77, 6 }; + int size = (1 << (getLog(ba.length) + 1))-1; + sa = new int[size]; + + build(0, 0, ba.length-1); + + System.out.println(query(0, 1, 4, 0, sa.length-1)); + } + +} diff --git a/sumRange.java b/sumRange.java new file mode 100644 index 0000000..3e6a1f5 --- /dev/null +++ b/sumRange.java @@ -0,0 +1,73 @@ +package SegTree; + +public class sumRange { + public int[] ba, sa; + + public int getLog(int n) { + int rv = 0; + while (n > 0) { + n = n >> 1; + ++rv; + } + return rv; + } + + public NumArray(int[] nums) { + int h=getLog(nums.length); + int sz = (1 << (h + 1)) - 1; + sa = new int[sz]; + ba=nums; + build(0,0,nums.length-1); + } + + public void build(int index, int ss, int se) { + if (ss == se) { + sa[index] = ba[ss]; + return; + } + + int mid = (ss + se) / 2; + build(2 * index + 1, ss, mid); + build(2 * index + 2, mid + 1, se); + + sa[index] = sa[index * 2 + 1] + sa[index * 2 + 2]; + + } + + public void update(int i, int val) { + update(0, i, val, 0, ba.lngth - 1); + } + + public void update(int vidx, int index, int val, int ss, int se) { + if (ss == se) { + sa[vidx] = val; + ba[se] = val; + } + int mid = (ss + se) / 2; + + if (index <= mid) { + update(vidx * 2 + 1, index, val, ss, mid); + } else { + update(vidx * 2 + 2, index, val, mid + 1, se); + } + + sa[vidx] = sa[vidx * 2 + 1] + sa[vidx * 2 + 2]; + } + + public int sumRange(int i, int j) { + return sumRange(0, i, j, 0, ba.length - 1); + } + + public int sumRange(int index, int qs, int qe, int ss, int se) { + if (qs <= ss && qe >= se) { + return sa[index]; + } else if (ss > qe || se < qs) { + return 0; + } else { + int mid = (ss + se) / 2; + int lv = sumRange(index * 2 + 1, qs, qe, ss, mid); + int rv = sumRange(index * 2 + 2, qs, qe, mid + 1, se); + return lv + rv; + } + } +}