<p>There are several squares being dropped onto the X-axis of a 2D plane.</p>

<p>You are given a 2D integer array <code>positions</code> where <code>positions[i] = [left<sub>i</sub>, sideLength<sub>i</sub>]</code> represents the <code>i<sup>th</sup></code> square with a side length of <code>sideLength<sub>i</sub></code> that is dropped with its left edge aligned with X-coordinate <code>left<sub>i</sub></code>.</p>

<p>Each square is dropped one at a time from a height above any landed squares. It then falls downward (negative Y direction) until it either lands <strong>on the top side of another square</strong> or <strong>on the X-axis</strong>. A square brushing the left/right side of another square does not count as landing on it. Once it lands, it freezes in place and cannot be moved.</p>

<p>After each square is dropped, you must record the <strong>height of the current tallest stack of squares</strong>.</p>

<p>Return <em>an integer array </em><code>ans</code><em> where </em><code>ans[i]</code><em> represents the height described above after dropping the </em><code>i<sup>th</sup></code><em> square</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/04/28/fallingsq1-plane.jpg" style="width: 500px; height: 505px;" />
<pre>
<strong>Input:</strong> positions = [[1,2],[2,3],[6,1]]
<strong>Output:</strong> [2,5,5]
<strong>Explanation:</strong>
After the first drop, the tallest stack is square 1 with a height of 2.
After the second drop, the tallest stack is squares 1 and 2 with a height of 5.
After the third drop, the tallest stack is still squares 1 and 2 with a height of 5.
Thus, we return an answer of [2, 5, 5].
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> positions = [[100,100],[200,100]]
<strong>Output:</strong> [100,100]
<strong>Explanation:</strong>
After the first drop, the tallest stack is square 1 with a height of 100.
After the second drop, the tallest stack is either square 1 or square 2, both with heights of 100.
Thus, we return an answer of [100, 100].
Note that square 2 only brushes the right side of square 1, which does not count as landing on it.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= positions.length &lt;= 1000</code></li>
	<li><code>1 &lt;= left<sub>i</sub> &lt;= 10<sup>8</sup></code></li>
	<li><code>1 &lt;= sideLength<sub>i</sub> &lt;= 10<sup>6</sup></code></li>
</ul>

class Solution {
public:
    const static int N = 1e5 + 2;
    int INF = 1e9;
    int tree[4 * N], lazy[4 * N], a[4*N];

    void build(int v, int tl, int tr) {
        if (tl == tr) {
            tree[v] = a[tl];
        } else {
            int tm = (tl + tr) / 2;
            build(v*2+1, tl, tm);
            build(v*2+2, tm+1, tr);
            tree[v] = max(tree[v*2+1], tree[v*2 + 2]);
        }
    }


    void push(int node){
        if(lazy[node]!=-1){
            tree[2*node] = lazy[node];
            tree[2*node+1] = lazy[node];

            lazy[2*node] = lazy[node];
            lazy[2*node+1] = lazy[node];
            lazy[node] = -1;
        }
    }

    void update(int node, int tl, int tr, int l, int r, int updatedVal){
        if (tl > tr)return;
        else if (l<=tl && tr <=r){
            tree[node] = updatedVal;
            lazy[node] = updatedVal; // ye value update krni hai tl to tr segment of segment tree.
        }
        else if(tl==tr && (tl<l||tr>r)) return;
        else{
            push(node);
            int tm = (tl + tr) / 2;
            update(2*node, tl, tm, l,r, updatedVal);
            update(2*node + 1, tm + 1, tr,l, r, updatedVal);
            tree[node] = max(tree[2*node], tree[2*node+ 1]);
        }
    }


    int query(int node, int tl, int tr, int l, int r){
        if (tl >tr) return -INF;
        if (l <= tl && tr <= r) return tree[node];
        if(tl==tr) return -INF;

        push(node);
        int tm = (tl + tr) / 2;
        int q1=query(2*node, tl, tm, l,r);
        int q2=query(2*node + 1, tm + 1, tr,l, r);
        return max(q1,q2);
    }


    vector<int> fallingSquares(vector<vector<int>>& pos) {
        memset(tree,0,sizeof(tree));
        memset(lazy,0,sizeof(lazy));
        memset(a,0,sizeof(a));

        


        unordered_map<int,int> mp;
        set<int> st;
        for(auto x : pos){
            st.insert(x[0]);
            st.insert(x[0]+x[1]-1);
        }

        int idx = 1;
        for(auto x : st){
            mp[x] = idx;
            idx++;
        }

        int n = idx;
        build(1, 1, n);
        vector<int> ans;
        for(auto x : pos){
            int l = mp[x[0]];
            int r = mp[x[0]+x[1]-1];

            int mxi = query(1, 1, n, l, r);
            update(1, 1, n, l, r, mxi+x[1]);

            int temp = query(1,1,n,1,n);
            ans.push_back(temp);
        }


        return ans;
    }
};
23315