Queries to update Subarrays of a given Array using Disjoint Set

Given an array arr[] consisting of N integers, consisting only of 0‘s initially and queries Q[][] of the form {L, R, C}, the task for each query is to update the subarray [L, R] with value C. Print the final array generated after performing all the queries.

Examples:

Input: N = 5, Q = {{1, 4, 1}, {3, 5, 2}, {2, 4, 3}} 
Output: 1 3 3 3 2 
Explanation: 
Initially, the array is {0, 0, 0, 0, 0} 
Query 1 modifies the array to {1, 1, 1, 1, 0} 
Query 2 modifies the array to {1, 1, 2, 2, 2} 
Query 3 modifies the array to {1, 3, 3, 3, 2}

Input: N = 3, Q = {{1, 2, 1}, {2, 3, 2}} 
Output: 1 2 2 
Explanation: 
Initially, the array is {0, 0, 0} 
Query 1 modifies the array to {1, 1, 0} 
Query 2 modifies the array to {1, 2, 2} 

Approach: The idea is to use Disjoint Set Union to solve the problem.Follow the steps below to solve the problem:



  • Initially, all the array elements will be considered as separate sets and parent of itself and will store the next array element with value 0.
  • First, store the query and process the queries in reverse order from last to first because the value assigned to each set will be final.
  • After processing the first query, elements with the changed value will point to the next element. This way on executing a query, we only have to assign values to the non-updated sets in the subarray [l, r]. All other cells already contain their final values.
  • Find the left-most non-updated set, and update it, and with the pointer, move to the next non-updated set to the right.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Maximum possible size of array
#define MAX_NODES 100005
  
// Stores the parent of each element
int parent[MAX_NODES];
  
// Stores the final array values
int final_val[MAX_NODES];
  
// Structure to store queries
struct query {
    int l, r, c;
};
  
// Function to initialize the
// parent of each vertex
void make_set(int v)
{
    // Initially parent
    // of each node points
    // to itself
    parent[v] = v;
}
  
// Function to find the representative
// of the set which contain element v
int find_set(int v)
{
    if (v == parent[v])
        return v;
  
    // Path compression
    return parent[v] = find_set(parent[v]);
}
  
// Function to assign a
// parent to each element
void Intialize(int n)
{
  
    for (int i = 0; i <= n; i++)
  
        make_set(i + 1);
}
  
// Function to process the queries
void Process(query Q[], int q)
{
  
    for (int i = q - 1; i >= 0; i--) {
  
        int l = Q[i].l, r = Q[i].r, c = Q[i].c;
  
        for (int v = find_set(l); v <= r;
             v = find_set(v)) {
  
            final_val[v] = c;
            parent[v] = v + 1;
        }
    }
}
  
// Function to print the final array
void PrintAns(int n)
{
  
    for (int i = 1; i <= n; i++) {
  
        cout << final_val[i] << " ";
    }
  
    cout << endl;
}
  
// Driver Code
int main()
{
    int n = 5;
  
    // Set all the elements as the
    // parent of itself using make_set
    Intialize(n);
  
    int q = 3;
    query Q[q];
  
    // Store the queries
    Q[0].l = 1, Q[0].r = 4, Q[0].c = 1;
    Q[1].l = 3, Q[1].r = 5, Q[1].c = 2;
    Q[2].l = 2, Q[2].r = 4, Q[2].c = 3;
  
    // Process the queries
    Process(Q, q);
  
    // Print the required array
    PrintAns(n);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
  
class GFG{
  
// Maximum possible size of array
static final int MAX_NODES = 100005;
  
// Stores the parent of each element
static int []parent = new int[MAX_NODES];
  
// Stores the final array values
static int []final_val = new int[MAX_NODES];
  
// Structure to store queries
static class query
{
    int l, r, c;
};
  
// Function to initialize the
// parent of each vertex
static void make_set(int v)
{
      
    // Initially parent
    // of each node points
    // to itself
    parent[v] = v;
}
  
// Function to find the representative
// of the set which contain element v
static int find_set(int v)
{
    if (v == parent[v])
        return v;
  
    // Path compression
    return parent[v] = find_set(parent[v]);
}
  
// Function to assign a
// parent to each element
static void Intialize(int n)
{
    for(int i = 0; i <= n; i++)
        make_set(i + 1);
}
  
// Function to process the queries
static void Process(query Q[], int q)
{
    for(int i = q - 1; i >= 0; i--)
    {
        int l = Q[i].l, r = Q[i].r, c = Q[i].c;
  
        for(int v = find_set(l); v <= r;
                v = find_set(v))
        {
            final_val[v] = c;
            parent[v] = v + 1;
        }
    }
}
  
// Function to print the final array
static void PrintAns(int n)
{
    for(int i = 1; i <= n; i++)
    {
        System.out.print(final_val[i] + " ");
    }
    System.out.println();
}
  
// Driver Code
public static void main(String[] args)
{
    int n = 5;
  
    // Set all the elements as the
    // parent of itself using make_set
    Intialize(n);
  
    int q = 3;
      
    query []Q = new query[q];
    for(int i = 0; i < Q.length; i++)
        Q[i] = new query();
          
    // Store the queries
    Q[0].l = 1; Q[0].r = 4; Q[0].c = 1;
    Q[1].l = 3; Q[1].r = 5; Q[1].c = 2;
    Q[2].l = 2; Q[2].r = 4; Q[2].c = 3;
  
    // Process the queries
    Process(Q, q);
  
    // Print the required array
    PrintAns(n);
}
}
  
// This code is contributed by amal kumar choubey

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
  
class GFG{
  
// Maximum possible size of array
static readonly int MAX_NODES = 100005;
  
// Stores the parent of each element
static int []parent = new int[MAX_NODES];
  
// Stores the readonly array values
static int []final_val = new int[MAX_NODES];
  
// Structure to store queries
class query
{
    public int l, r, c;
};
  
// Function to initialize the
// parent of each vertex
static void make_set(int v)
{
      
    // Initially parent
    // of each node points
    // to itself
    parent[v] = v;
}
  
// Function to find the representative
// of the set which contain element v
static int find_set(int v)
{
    if (v == parent[v])
        return v;
  
    // Path compression
    return parent[v] = find_set(parent[v]);
}
  
// Function to assign a
// parent to each element
static void Intialize(int n)
{
    for(int i = 0; i <= n; i++)
        make_set(i + 1);
}
  
// Function to process the queries
static void Process(query []Q, int q)
{
    for(int i = q - 1; i >= 0; i--)
    {
        int l = Q[i].l, r = Q[i].r, c = Q[i].c;
  
        for(int v = find_set(l); v <= r;
                v = find_set(v))
        {
            final_val[v] = c;
            parent[v] = v + 1;
        }
    }
}
  
// Function to print the readonly array
static void PrintAns(int n)
{
    for(int i = 1; i <= n; i++)
    {
        Console.Write(final_val[i] + " ");
    }
    Console.WriteLine();
}
  
// Driver Code
public static void Main(String[] args)
{
    int n = 5;
  
    // Set all the elements as the
    // parent of itself using make_set
    Intialize(n);
  
    int q = 3;
      
    query []Q = new query[q];
    for(int i = 0; i < Q.Length; i++)
        Q[i] = new query();
          
    // Store the queries
    Q[0].l = 1; Q[0].r = 4; Q[0].c = 1;
    Q[1].l = 3; Q[1].r = 5; Q[1].c = 2;
    Q[2].l = 2; Q[2].r = 4; Q[2].c = 3;
  
    // Process the queries
    Process(Q, q);
  
    // Print the required array
    PrintAns(n);
}
}
  
// This code is contributed by amal kumar choubey 

chevron_right


Output: 

1 3 3 3 2

Time complexity: O(log N) 
Auxiliary Space: O(MAX_NODES)
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Amal Kumar Choubey