Actualización de rango sin usar propagación diferida y consulta de puntos en un árbol de segmentos

Dada una array arr[] que consta de N 0 s y una array 2D Q[][] que consta de consultas de los siguientes dos tipos:

  • 1 LRX: Incrementa todos los elementos en el rango [L, R] por X .
  • 2 X: Imprime elementos en el índice X de la array.

Entrada: arr[] = { 0, 0, 0, 0, 0 }, Q[][] = { { 1, 0, 2, 100 }, { 2, 1 }, { 1, 2, 3, 200 } , { 2, 2 }, { 
4 } } 
Salida: 100 300 0 
Explicación: 
Consulta 1: Incrementar todos los elementos de la array en el rango [0, 2] en 100 modifica arr[] a { 100, 100, 100, 0, 0 }. 
Consulta2: Imprimir arr[1](=100) 
Consulta3: Incrementar todos los elementos de la array en el rango [2, 3] en 200 modifica arr[] a { 100, 100, 300, 200, 0 }. 
Consulta 4: Imprimir array [2] (= 300) 
Consulta 5: Imprimir array [4] (= 0)

Entrada: arr[] = { 0, 0 }, Q[][] = { { 1, 0, 1, 100 }, { 2, 1 } } 
Salida: 100

Enfoque: La idea es utilizar el concepto de árbol de segmentos para realizar consultas de tipo 2 y la array de diferencias para realizar consultas de tipo 1 . Siga los pasos a continuación para resolver el problema:

A continuación se muestra la implementación del enfoque anterior:

C++

// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
void update(int Tree[], int idx, int s,
            int e, int pos, int X)
{
    // If current node is a
    // leaf nodes
    if (s == e) {
 
        // Update Tree[idx]
        Tree[idx] += X;
    }
 
    else {
 
        // Divide segment tree into left
        // and right subtree
        int m = (s + e) / 2;
 
        // Check if pos lies in left subtree
        if (pos <= m) {
 
            // Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X);
        }
        else {
 
            // Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,
                   pos, X);
        }
 
        // Update Tree[idx]
        Tree[idx]
            = Tree[2 * idx] + Tree[2 * idx + 1];
    }
}
 
// Function to find the sum from
// elements in the range [0, X]
int sum(int Tree[], int idx, int s,
        int e, int ql, int qr)
{
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
        return Tree[idx];
 
    if (ql > qr)
        return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    int m = (s + e) / 2;
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, min(m, qr))
           + sum(Tree, 2 * idx + 1, m + 1, e,
                 max(ql, m + 1), qr);
}
 
// Function to find Xth element
// in the array
void getElement(int Tree[], int X, int N)
{
    // Print element at index x
    cout << "Element at " << X << " is "
         << sum(Tree, 1, 0, N - 1, 0, X) << endl;
}
 
// Function to update array elements
// in the range [L, R]
void range_Update(int Tree[], int L,
                  int R, int X, int N)
{
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
        update(Tree, 1, 0, N - 1, R + 1, -X);
}
 
// Drivers Code
int main()
{
    // Size of array
    int N = 5;
 
    int Tree[4 * N + 5] = { 0 };
 
    int arr[] = { 0, 0 };
    vector<vector<int> >
        Q = { { 1, 0, 1, 100 }, { 2, 1 } };
 
    int cntQuery = Q.size();
    for (int i = 0; i < cntQuery; i++) {
 
        if (Q[i][0] == 1) {
 
            range_Update(Tree, Q[i][1],
                         Q[i][2], Q[i][3], N);
        }
        else {
 
            getElement(Tree, Q[i][1], N);
        }
    }
}

Java

// Java program to implement
// the above approach
import java.util.*;
class GFG
{
 
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
static void update(int Tree[], int idx, int s,
            int e, int pos, int X)
{
   
    // If current node is a
    // leaf nodes
    if (s == e)
    {
 
        // Update Tree[idx]
        Tree[idx] += X;
    }
 
    else
    {
 
        // Divide segment tree into left
        // and right subtree
        int m = (s + e) / 2;
 
        // Check if pos lies in left subtree
        if (pos <= m)
        {
 
            // Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X);
        }
        else
        {
 
            // Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,
                   pos, X);
        }
 
        // Update Tree[idx]
        Tree[idx]
            = Tree[2 * idx] + Tree[2 * idx + 1];
    }
}
 
// Function to find the sum from
// elements in the range [0, X]
static int sum(int Tree[], int idx, int s,
        int e, int ql, int qr)
{
   
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
        return Tree[idx];
 
    if (ql > qr)
        return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    int m = (s + e) / 2;
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
           + sum(Tree, 2 * idx + 1, m + 1, e,
                 Math.max(ql, m + 1), qr);
}
 
// Function to find Xth element
// in the array
static void getElement(int Tree[], int X, int N)
{
   
    // Print element at index x
    System.out.print("Element at " +  X+ " is "
         + sum(Tree, 1, 0, N - 1, 0, X) +"\n");
}
 
// Function to update array elements
// in the range [L, R]
static void range_Update(int Tree[], int L,
                  int R, int X, int N)
{
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
        update(Tree, 1, 0, N - 1, R + 1, -X);
}
 
// Drivers Code
public static void main(String[] args)
{
   
    // Size of array
    int N = 5;
    int Tree[] = new int[4 * N + 5];
    int arr[] = { 0, 0 };
    int[][]
        Q = { { 1, 0, 1, 100 }, { 2, 1 } };
    int cntQuery = Q.length;
    for (int i = 0; i < cntQuery; i++)
    {
        if (Q[i][0] == 1)
        {
            range_Update(Tree, Q[i][1],
                         Q[i][2], Q[i][3], N);
        }
        else
        {
            getElement(Tree, Q[i][1], N);
        }
    }
}
}
 
// This code is contributed by shikhasingrajput

Python3

# Python3 program to implement
# the above approach
 
# Function to update the array elements
# at idx pos, i.e arr[pos] += X
def update(Tree, idx, s, e, pos, X):
   
    # If current node is a
    # leaf nodes
    if (s == e):
 
        # Update Tree[idx]
        Tree[idx] += X
 
    else:
 
        # Divide segment tree into left
        # and right subtree
        m = (s + e) // 2
 
        # Check if pos lies in left subtree
        if (pos <= m):
 
            # Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X)
        else:
 
            # Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,pos, X)
 
        # Update Tree[idx]
        Tree[idx] = Tree[2 * idx] + Tree[2 * idx + 1]
 
# Function to find the sum from
# elements in the range [0, X]
def sum(Tree, idx, s, e, ql, qr):
   
    # Check if range[ql, qr] equals
    # to range [s, e]
    if (ql == s and qr == e):
        return Tree[idx]
 
    if (ql > qr):
        return 0
 
    # Divide segment tree into
    # left subtree and
    # right subtree
    m = (s + e) // 2
 
    # Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, min(m, qr))+ sum(Tree, 2 * idx + 1, m + 1, e,max(ql, m + 1), qr)
 
# Function to find Xth element
# in the array
def getElement(Tree, X, N):
   
    # Print element at index x
    print("Element at", X, "is ", sum(Tree, 1, 0, N - 1, 0, X))
 
# Function to update array elements
# in the range [L, R]
def range_Update(Tree, L, R, X, N):
 
    # Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X)
 
    # Update arr[R + 1] += X
    if (R + 1 < N):
        update(Tree, 1, 0, N - 1, R + 1, -X)
 
# Drivers Code
if __name__ == '__main__':
   
    # Size of array
    N = 5
    Tree = [0]*(4 * N + 5)
    arr = [0, 0]
    Q = [ [1, 0, 1, 100], [2, 1] ]
    cntQuery = len(Q)
    for i in range(cntQuery):
        if (Q[i][0] == 1):
            range_Update(Tree, Q[i][1], Q[i][2], Q[i][3], N)
        else:
            getElement(Tree, Q[i][1], N)
 
# This code is contributed by mohit kumar 29.

C#

// C# program to implement
// the above approach
using System;
public class GFG
{
 
  // Function to update the array elements
  // at idx pos, i.e arr[pos] += X
  static void update(int []Tree, int idx, int s,
                     int e, int pos, int X)
  {
 
    // If current node is a
    // leaf nodes
    if (s == e)
    {
 
      // Update Tree[idx]
      Tree[idx] += X;
    }
 
    else
    {
 
      // Divide segment tree into left
      // and right subtree
      int m = (s + e) / 2;
 
      // Check if pos lies in left subtree
      if (pos <= m)
      {
 
        // Search pos in left subtree
        update(Tree, 2 * idx, s, m, pos, X);
      }
      else
      {
 
        // Search pos in right subtree
        update(Tree, 2 * idx + 1, m + 1, e,
               pos, X);
      }
 
      // Update Tree[idx]
      Tree[idx]
        = Tree[2 * idx] + Tree[2 * idx + 1];
    }
  }
 
  // Function to find the sum from
  // elements in the range [0, X]
  static int sum(int []Tree, int idx, int s,
                 int e, int ql, int qr)
  {
 
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
      return Tree[idx];
 
    if (ql > qr)
      return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    int m = (s + e) / 2;
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, Math.Min(m, qr))
      + sum(Tree, 2 * idx + 1, m + 1, e,
            Math.Max(ql, m + 1), qr);
  }
 
  // Function to find Xth element
  // in the array
  static void getElement(int []Tree, int X, int N)
  {
 
    // Print element at index x
    Console.Write("Element at " +  X+ " is "
                  + sum(Tree, 1, 0, N - 1, 0, X) +"\n");
  }
 
  // Function to update array elements
  // in the range [L, R]
  static void range_Update(int []Tree, int L,
                           int R, int X, int N)
  {
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
      update(Tree, 1, 0, N - 1, R + 1, -X);
  }
 
  // Drivers Code
  public static void Main(String[] args)
  {
 
    // Size of array
    int N = 5;
    int []Tree = new int[4 * N + 5];
    int []arr = { 0, 0 };
    int[,]Q = { { 1, 0, 1, 100 }, { 2, 1, 0, 0 } };
    int cntQuery = Q.GetLength(0);
    for (int i = 0; i < cntQuery; i++)
    {
      if (Q[i, 0] == 1)
      {
        range_Update(Tree, Q[i, 1],
                     Q[i, 2], Q[i, 3], N);
      }
      else
      {
        getElement(Tree, Q[i, 1], N);
      }
    }
  }
}
 
// This code is contributed by 29AjayKumar

Javascript

<script>
 
// Javascript program to implement
// the above approach
 
// Function to update the array elements
// at idx pos, i.e arr[pos] += X
function update(Tree, idx, s, e, pos, X)
{
    // If current node is a
    // leaf nodes
    if (s == e) {
 
        // Update Tree[idx]
        Tree[idx] += X;
    }
 
    else {
 
        // Divide segment tree into left
        // and right subtree
        var m = parseInt((s + e) / 2);
 
        // Check if pos lies in left subtree
        if (pos <= m) {
 
            // Search pos in left subtree
            update(Tree, 2 * idx, s, m, pos, X);
        }
        else {
 
            // Search pos in right subtree
            update(Tree, 2 * idx + 1, m + 1, e,
                   pos, X);
        }
 
        // Update Tree[idx]
        Tree[idx]
            = Tree[2 * idx] + Tree[2 * idx + 1];
    }
}
 
// Function to find the sum from
// elements in the range [0, X]
function sum(Tree, idx, s, e, ql, qr)
{
    // Check if range[ql, qr] equals
    // to range [s, e]
    if (ql == s && qr == e)
        return Tree[idx];
 
    if (ql > qr)
        return 0;
 
    // Divide segment tree into
    // left subtree and
    // right subtree
    var m =parseInt((s + e) / 2);
 
    // Return sum of elements in the range[ql, qr]
    return sum(Tree, 2 * idx, s, m, ql, Math.min(m, qr))
           + sum(Tree, 2 * idx + 1, m + 1, e,
                 Math.max(ql, m + 1), qr);
}
 
// Function to find Xth element
// in the array
function getElement(Tree, X, N)
{
    // Print element at index x
    document.write( "Element at " + X + " is "
         + sum(Tree, 1, 0, N - 1, 0, X) );
}
 
// Function to update array elements
// in the range [L, R]
function range_Update(Tree, L, R, X, N)
{
 
    // Update arr[l] += X
    update(Tree, 1, 0, N - 1, L, X);
 
    // Update arr[R + 1] += X
    if (R + 1 < N)
        update(Tree, 1, 0, N - 1, R + 1, -X);
}
 
// Drivers Code
// Size of array
var N = 5;
var Tree = Array(4 * N + 5).fill(0);
var arr = [ 0, 0 ];
var Q = [[ 1, 0, 1, 100 ], [ 2, 1 ]];
var cntQuery = Q.length;
for (var i = 0; i < cntQuery; i++) {
    if (Q[i][0] == 1) {
        range_Update(Tree, Q[i][1],
                     Q[i][2], Q[i][3], N);
    }
    else {
        getElement(Tree, Q[i][1], N);
    }
}
 
 
</script>
Producción: 

Element at 1 is 100

 

Complejidad de tiempo: O(|Q| * log(N))
Espacio auxiliar: O(N)

Publicación traducida automáticamente

Artículo escrito por single__loop y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *