💥 Beats 100% on memory [EXPLAINED]
IntuitionTrack the connections between different parts of a structure and update their values efficiently. The task is to manage the union of elements and perfo
# Intuition
Track the connections between different parts of a structure and update their values efficiently. The task is to manage the union of elements and perform range queries, so I need a way to represent and efficiently manipulate the connected components and their corresponding costs.

# Approach
Use a disjoint-set (union-find) to keep track of the connected components and their costs, a segment tree to handle the range queries and updates, and I process the queries in reverse order, updating the components and checking if certain conditions hold. The segment tree helps manage the maximum cost over ranges, while the disjoint-set manages the merging of components. By reversing the queries, I can efficiently merge and query the structure.

# Complexity
- Time complexity:
O(N log N) for updates and queries due to the segment tree and union-find operations.

- Space complexity:
 O(N) for storing the segment tree, parent array, block array, and costs.

# Code
```kotlin []
class Solution {

    val inf: Long = 1e18.toLong()

    val block = LongArray(50005)
    val parent = IntArray(50005)
    val cost = LongArray(50005)

    val seg = LongArray(200020)

    fun upd(node: Int, l: Int, r: Int, idx: Int, `val`: Long) {
        if (idx < l || idx > r) return
        if (l >= r) {
            if (l == idx) {
                seg[node] = `val`
            }
            return
        }
        val mid = l + (r - l) / 2
        val lNode = 2 * node + 1
        val rNode = 2 * node + 2
        upd(lNode, l, mid, idx, `val`)
        upd(rNode, mid + 1, r, idx, `val`)
        seg[node] = maxOf(seg[lNode], seg[rNode])
    }

    fun query(node: Int, l: Int, r: Int, lQuery: Int, rQuery: Int): Long {
        if (lQuery <= l && rQuery >= r) return seg[node]
        if (lQuery > r || rQuery < l) return -inf
        val mid = l + (r - l) / 2
        val lNode = 2 * node + 1
        val rNode = 2 * node + 2
        return maxOf(query(lNode, l, mid, lQuery, rQuery), query(rNode, mid + 1, r, lQuery, rQuery))
    }

    fun root(p: Int): Int {
        return if (p == parent[p]) p else {
            parent[p] = root(parent[p])
            parent[p]
        }
    }

    fun getResults(queries: Array<IntArray>): List<Boolean> {
        val n = 50000
        seg.fill(0)

        for (e in queries) {
            if (e[0] == 1) {
                val x = e[1]
                block[x] = 1L  // Fix the type mismatch by using `1L` for Long
            }
        }

        block[n] = 1L // last segment
        var par = 0
        var cnt = 0
        for (i in 1..n) {
            parent[i] = par
            cnt++
            if (block[i] == 1L) {  // Fix the type mismatch by using `1L` for Long
                cost[par] = cnt.toLong()
                upd(0, 0, n - 1, par, cost[par])
                cnt = 0
                par = i + 1
            }
        }

        val reversedQueries = queries.reversed()
        val ans = mutableListOf<Boolean>()
        for (e in reversedQueries) {
            if (e[0] == 1) {
                val x = e[1]
                val u = root(x)
                val v = root(x + 1)
                if (u == v) continue
                parent[v] = u
                cost[u] += cost[v]
                upd(0, 0, n - 1, u, cost[u])
            } else {
                val x = e[1]
                val sz = e[2]
                val v = root(x)
                upd(0, 0, n - 1, v, x - maxOf(0, v - 1).toLong())
                val value = query(0, 0, n - 1, 0, v)
                upd(0, 0, n - 1, v, cost[v])
                ans.add(value >= sz)
            }
        }

        return ans.reversed()
    }
}

```
['Array', 'Hash Table', 'Binary Search', 'Dynamic Programming', 'Binary Indexed Tree', 'Segment Tree', 'Binary Search Tree', 'Ordered Map', 'Simulation', 'Kotlin']