Consultas para calcular la suma alternando signos de elementos de array en un rango dado

Dada una array arr[] de tamaño N y una array 2D Q[][] , que consta de consultas de los siguientes dos tipos:

Ejemplos:

Entrada: arr[] = { 1, 2, 3, 4 }, Q[][] = { { 2, 0, 3 }, { 1, 1, 5 }, { 2, 1, 2 } } 
Salida: – 2 2 
Explicación: 
Consulta1: Imprimir (arr[0] – arr[1] + arr[2] – arr[3]) = 1 – 2 + 3 – 4 = -2 
Consulta2: Actualizar arr[1] a 5 modifica arr [] a { 1, 5, 3, 4 } 
Consulta 3: Imprimir (arr[1] – arr[2]) = 5 – 3 = 2

Entrada: arr[] = { 4, 2, 6, 1, 8, 9, 2}, Q = { { 2, 1, 4 }, { 1, 3, 4 }, { 2, 0, 3 } } 
Salida : -11 5

Enfoque: El problema se puede resolver utilizando Segment Tree . La idea es recorrer la array y verificar si el índice del elemento de la array es negativo y luego multiplicar los elementos de la array por -1 . Siga los pasos a continuación para resolver el problema:

  • Recorra la array arr[] usando la variable i y verifique si el índice i es impar o no. Si se determina que es cierto, actualice arr[i] = -Val .
  • Para consultas de tipo 1, X, Val , verifique si X es par o no. Si se determina que es cierto, actualice arr[X] = Val usando el árbol de segmentos .
  • De lo contrario, actualice arr[X] = -Val utilizando el árbol de segmentos.
  • Para consultas de tipo 2 LR: , verifique si L es par o no. Si se determina que es cierto, imprima la suma de los elementos de la array en el rango [L, R] utilizando el árbol de segmentos .
  • De lo contrario, encuentre la suma de los elementos de la array en el rango [L, R] utilizando el árbol de segmentos e imprima la suma obtenida multiplicando por -1 .

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 build the segment tree
void build(int tree[], int arr[], int start,
           int end, int index)
{
 
    // If current node is a leaf node
    // of the segment tree
    if (start == end) {
 
        if (start % 2 == 0) {
 
            // Update tree[index]
            tree[index] = arr[start];
        }
 
        else {
 
            // Update tree[index]
            tree[index] = -arr[start];
        }
        return;
    }
 
    // Divide the segment tree
    int mid = start + (end - start) / 2;
 
    // Update on L segment tree
    build(tree, arr, start, mid,
          2 * index + 1);
 
    // Update on R segment tree
    build(tree, arr, mid + 1, end,
          2 * index + 2);
 
    // Find the sum from L subtree
    // and R subtree
    tree[index] = tree[2 * index + 1] + tree[2 * index + 2];
}
 
// Function to update elements at index pos
// by val in the segment tree
void update(int tree[], int index, int start,
            int end, int pos, int val)
{
 
    // If current node is a leaf node
    if (start == end) {
 
        // If current index is even
        if (start % 2 == 0) {
 
            // Update tree[index]
            tree[index] = val;
        }
 
        else {
 
            // Update tree[index]
            tree[index] = -val;
        }
        return;
    }
 
    // Divide the segment tree elements
    // into L and R subtree
    int mid = start + (end - start) / 2;
 
    // If element lies in L subtree
    if (mid >= pos) {
 
        update(tree, 2 * index + 1, start,
               mid, pos, val);
    }
    else {
        update(tree, 2 * index + 2, mid + 1,
               end, pos, val);
    }
 
    // Update tree[index]
    tree[index]
        = tree[2 * index + 1] + tree[2 * index + 2];
}
 
// Function to find the sum of array elements
// in the range [L, R]
int FindSum(int tree[], int start, int end,
            int L, int R, int index)
{
 
    // If start and end not lies in
    // the range [L, R]
    if (L > end || R < start) {
        return 0;
    }
 
    // If start and end comleately lies
    // in the range [L, R]
    if (L <= start && R >= end) {
 
        return tree[index];
    }
    int mid = start + (end - start) / 2;
 
    // Stores sum from left subtree
    int X = FindSum(tree, start, mid, L,
                    R, 2 * index + 1);
 
    // Stores sum from right subtree
    int Y = FindSum(tree, mid + 1, end, L,
                    R, 2 * index + 2);
 
    return X + Y;
}
 
int main()
{
 
    int arr[] = { 1, 2, 3, 4 };
    int N = sizeof(arr) / sizeof(arr[0]);
    int tree[4 * N + 5] = { 0 };
    build(tree, arr, 0, N - 1, 0);
 
    int Q[][3] = { { 2, 0, 3 }, { 1, 1, 5 }, { 2, 1, 2 } };
 
    int cntQuey = 3;
    for (int i = 0; i < cntQuey; i++) {
 
        if (Q[i][0] == 1) {
 
            update(tree, 0, 0, N - 1,
                   Q[i][1], Q[i][2]);
        }
 
        else {
 
            if (Q[i][1] % 2 == 0) {
 
                cout << FindSum(tree, 0, N - 1,
                                Q[i][1], Q[i][2], 0)
                     << " ";
            }
            else {
 
                cout << -FindSum(tree, 0, N - 1,
                                 Q[i][1], Q[i][2], 0)
                     << " ";
            }
        }
    }
}

Java

// Java program to implement
// the above approach
import java.util.*;
  
class GFG{
  
// Function to build the segment tree
static void build(int tree[], int arr[], int start,
           int end, int index)
{
 
    // If current node is a leaf node
    // of the segment tree
    if (start == end) {
 
        if (start % 2 == 0) {
 
            // Update tree[index]
            tree[index] = arr[start];
        }
 
        else {
 
            // Update tree[index]
            tree[index] = -arr[start];
        }
        return;
    }
 
    // Divide the segment tree
    int mid = start + (end - start) / 2;
 
    // Update on L segment tree
    build(tree, arr, start, mid,
          2 * index + 1);
 
    // Update on R segment tree
    build(tree, arr, mid + 1, end,
          2 * index + 2);
 
    // Find the sum from L subtree
    // and R subtree
    tree[index] = tree[2 * index + 1] + tree[2 * index + 2];
}
 
// Function to update elements at index pos
// by val in the segment tree
static void update(int tree[], int index, int start,
            int end, int pos, int val)
{
 
    // If current node is a leaf node
    if (start == end) {
 
        // If current index is even
        if (start % 2 == 0) {
 
            // Update tree[index]
            tree[index] = val;
        }
 
        else {
 
            // Update tree[index]
            tree[index] = -val;
        }
        return;
    }
 
    // Divide the segment tree elements
    // into L and R subtree
    int mid = start + (end - start) / 2;
 
    // If element lies in L subtree
    if (mid >= pos)
    {
        update(tree, 2 * index + 1, start,
               mid, pos, val);
    }
    else
    {
        update(tree, 2 * index + 2, mid + 1,
               end, pos, val);
    }
 
    // Update tree[index]
    tree[index]
        = tree[2 * index + 1] + tree[2 * index + 2];
}
 
// Function to find the sum of array elements
// in the range [L, R]
static int FindSum(int tree[], int start, int end,
            int L, int R, int index)
{
 
    // If start and end not lies in
    // the range [L, R]
    if (L > end || R < start)
    {
        return 0;
    }
 
    // If start and end comleately lies
    // in the range [L, R]
    if (L <= start && R >= end)
    {
        return tree[index];
    }
    int mid = start + (end - start) / 2;
 
    // Stores sum from left subtree
    int X = FindSum(tree, start, mid, L,
                    R, 2 * index + 1);
 
    // Stores sum from right subtree
    int Y = FindSum(tree, mid + 1, end, L,
                    R, 2 * index + 2);
    return X + Y;
}
  
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 1, 2, 3, 4 };
    int N = arr.length;
    int tree[] = new int[4 * N + 5];
    Arrays.fill(tree, 0);
    build(tree, arr, 0, N - 1, 0);
    int Q[][] = { { 2, 0, 3 }, { 1, 1, 5 }, { 2, 1, 2 } };
    int cntQuey = 3;
    for (int i = 0; i < cntQuey; i++)
    {
        if (Q[i][0] == 1)
        {
            update(tree, 0, 0, N - 1,
                   Q[i][1], Q[i][2]);
        }
        else {
            if (Q[i][1] % 2 == 0)
            {
                System.out.print(FindSum(tree, 0, N - 1,
                                Q[i][1], Q[i][2], 0) + " ");
            }
            else
            {
                System.out.print(-FindSum(tree, 0, N - 1,
                                 Q[i][1], Q[i][2], 0)+ " ");
            }
        }
    }
}
}
 
// This code is contributed by code_hunt.

Python3

# Python3  program to implement
# the above approach
 
# Function to build the segment tree
def build(tree, arr, start, end, index):
 
    # If current node is a leaf node
    # of the segment tree
    if (start == end):
        if (start % 2 == 0):
 
            # Update tree[index]
            tree[index] = arr[start]
        else:
 
            # Update tree[index]
            tree[index] = -arr[start]
        return
 
    # Divide the segment tree
    mid = start + (end - start) // 2
 
    # Update on L segment tree
    build(tree, arr, start, mid, 2 * index + 1)
 
    # Update on R segment tree
    build(tree, arr, mid + 1, end, 2 * index + 2)
 
    # Find the sum from L subtree
    # and R subtree
    tree[index] = tree[2 * index + 1] + tree[2 * index + 2]
 
# Function to update elements at index pos
# by val in the segment tree
def update(tree, index, start, end, pos, val):
 
    # If current node is a leaf node
    if (start == end):
 
        # If current index is even
        if (start % 2 == 0):
 
            # Update tree[index]
            tree[index] = val
        else:
 
            # Update tree[index]
            tree[index] = -val
        return
 
    # Divide the segment tree elements
    # into L and R subtree
    mid = start + (end - start) // 2
 
    # If element lies in L subtree
    if (mid >= pos):
        update(tree, 2 * index + 1, start, mid, pos, val)
    else:
        update(tree, 2 * index + 2, mid + 1, end, pos, val)
 
    # Update tree[index]
    tree[index] = tree[2 * index + 1] + tree[2 * index + 2]
 
# Function to find the sum of array elements
# in the range [L, R]
def FindSum(tree, start, end, L, R, index):
 
    # If start and end not lies in
    # the range [L, R]
    if (L > end or R < start):
        return 0
 
    #If start and end comleately lies
    #in the range [L, R]
    if (L <= start and R >= end):
        return tree[index]
    mid = start + (end - start) // 2
 
    # Stores sum from left subtree
    X = FindSum(tree, start, mid, L, R, 2 * index + 1)
 
    # Stores sum from right subtree
    Y = FindSum(tree, mid + 1, end, L, R, 2 * index + 2)
 
    return X + Y
 
  # Driver code
if __name__ == '__main__':
 
    arr = [1, 2, 3, 4]
    N = len(arr)
    tree = [0 for i in range(4 * N + 5)]
    build(tree, arr, 0, N - 1, 0)
    Q = [ [ 2, 0, 3 ], [ 1, 1, 5 ], [ 2, 1, 2 ] ]
    cntQuey = 3
    for i in range(cntQuey):
        if (Q[i][0] == 1):
            update(tree, 0, 0, N - 1, Q[i][1], Q[i][2])
        else:
            if (Q[i][1] % 2 == 0):
                print(FindSum(tree, 0, N - 1, Q[i][1], Q[i][2], 0),end=" ")
            else:
                print(-FindSum(tree, 0, N - 1, Q[i][1], Q[i][2], 0),end=" ")
                 
# This code is contributed by mohit kumar 29

C#

// C#  program to implement
// the above approach
using System;
class GFG
{
     
    // Function to build the segment tree
    static void build(int[] tree, int[] arr, int start,
               int end, int index)
    {
      
        // If current node is a leaf node
        // of the segment tree
        if (start == end)
        {  
            if (start % 2 == 0)
            {
      
                // Update tree[index]
                tree[index] = arr[start];
            }
      
            else
            {
      
                // Update tree[index]
                tree[index] = -arr[start];
            }
            return;
        }
      
        // Divide the segment tree
        int mid = start + (end - start) / 2;
      
        // Update on L segment tree
        build(tree, arr, start, mid,
              2 * index + 1);
      
        // Update on R segment tree
        build(tree, arr, mid + 1, end,
              2 * index + 2);
      
        // Find the sum from L subtree
        // and R subtree
        tree[index] = tree[2 * index + 1] + tree[2 * index + 2];
    }
      
    // Function to update elements at index pos
    // by val in the segment tree
    static void update(int[] tree, int index, int start,
                int end, int pos, int val)
    {
      
        // If current node is a leaf node
        if (start == end)
        {
      
            // If current index is even
            if (start % 2 == 0)
            {
      
                // Update tree[index]
                tree[index] = val;
            }
      
            else
            {
      
                // Update tree[index]
                tree[index] = -val;
            }
            return;
        }
      
        // Divide the segment tree elements
        // into L and R subtree
        int mid = start + (end - start) / 2;
      
        // If element lies in L subtree
        if (mid >= pos)
        {
      
            update(tree, 2 * index + 1, start,
                   mid, pos, val);
        }
        else
        {
            update(tree, 2 * index + 2, mid + 1,
                   end, pos, val);
        }
      
        // Update tree[index]
        tree[index]
            = tree[2 * index + 1] + tree[2 * index + 2];
    }
      
    // Function to find the sum of array elements
    // in the range [L, R]
    static int FindSum(int[] tree, int start, int end,
                int L, int R, int index)
    {
      
        // If start and end not lies in
        // the range [L, R]
        if (L > end || R < start)
        {
            return 0;
        }
      
        // If start and end comleately lies
        // in the range [L, R]
        if (L <= start && R >= end)
        {
      
            return tree[index];
        }
        int mid = start + (end - start) / 2;
      
        // Stores sum from left subtree
        int X = FindSum(tree, start, mid, L,
                        R, 2 * index + 1);
      
        // Stores sum from right subtree
        int Y = FindSum(tree, mid + 1, end, L,
                        R, 2 * index + 2);
      
        return X + Y;
    }
 
  // Driver code
  static void Main()
  {
    int[] arr = { 1, 2, 3, 4 };
    int N = arr.Length;
    int[] tree = new int[4 * N + 5];
    build(tree, arr, 0, N - 1, 0);
  
    int[,] Q = { { 2, 0, 3 }, { 1, 1, 5 }, { 2, 1, 2 } };
  
    int cntQuey = 3;
    for (int i = 0; i < cntQuey; i++)
    {
        if (Q[i, 0] == 1)
        {
            update(tree, 0, 0, N - 1,
                   Q[i, 1], Q[i, 2]);
        }
  
        else
        {
            if (Q[i, 1] % 2 == 0)
            {
                Console.Write(FindSum(tree, 0, N - 1,
                                      Q[i, 1], Q[i, 2], 0) + " ");
            }
            else
            {
                Console.Write(-FindSum(tree, 0, N - 1,
                                       Q[i, 1], Q[i, 2], 0) + " ");
            }
        }
    }
  }
}
 
// This code is contributed by divyesh072019.

Javascript

<script>
 
// Javascript  program to implement
// the above approach
 
// Function to build the segment tree
function build(tree, arr, start, end, index)
{
 
    // If current node is a leaf node
    // of the segment tree
    if (start == end) {
 
        if (start % 2 == 0) {
 
            // Update tree[index]
            tree[index] = arr[start];
        }
 
        else {
 
            // Update tree[index]
            tree[index] = -arr[start];
        }
        return;
    }
 
    // Divide the segment tree
    var mid = start + parseInt((end - start) / 2);
 
    // Update on L segment tree
    build(tree, arr, start, mid,
          2 * index + 1);
 
    // Update on R segment tree
    build(tree, arr, mid + 1, end,
          2 * index + 2);
 
    // Find the sum from L subtree
    // and R subtree
    tree[index] = tree[2 * index + 1] + tree[2 * index + 2];
}
 
// Function to update elements at index pos
// by val in the segment tree
function update(tree, index, start, end, pos, val)
{
 
    // If current node is a leaf node
    if (start == end) {
 
        // If current index is even
        if (start % 2 == 0) {
 
            // Update tree[index]
            tree[index] = val;
        }
 
        else {
 
            // Update tree[index]
            tree[index] = -val;
        }
        return;
    }
 
    // Divide the segment tree elements
    // into L and R subtree
    var mid = start + parseInt((end - start) / 2);
 
    // If element lies in L subtree
    if (mid >= pos) {
 
        update(tree, 2 * index + 1, start,
               mid, pos, val);
    }
    else {
        update(tree, 2 * index + 2, mid + 1,
               end, pos, val);
    }
 
    // Update tree[index]
    tree[index]
        = tree[2 * index + 1] + tree[2 * index + 2];
}
 
// Function to find the sum of array elements
// in the range [L, R]
function FindSum(tree, start, end, L, R, index)
{
 
    // If start and end not lies in
    // the range [L, R]
    if (L > end || R < start) {
        return 0;
    }
 
    // If start and end comleately lies
    // in the range [L, R]
    if (L <= start && R >= end) {
 
        return tree[index];
    }
    var mid = start + parseInt((end - start) / 2);
 
    // Stores sum from left subtree
    var X = FindSum(tree, start, mid, L,
                    R, 2 * index + 1);
 
    // Stores sum from right subtree
    var Y = FindSum(tree, mid + 1, end, L,
                    R, 2 * index + 2);
 
    return X + Y;
}
 
var arr = [1, 2, 3, 4 ];
var N = arr.length;
var tree = Array(4*N+5).fill(0);
build(tree, arr, 0, N - 1, 0);
var Q = [ [ 2, 0, 3 ], [ 1, 1, 5 ], [ 2, 1, 2 ] ];
var cntQuey = 3;
for (var i = 0; i < cntQuey; i++) {
    if (Q[i][0] == 1) {
        update(tree, 0, 0, N - 1,
               Q[i][1], Q[i][2]);
    }
    else {
        if (Q[i][1] % 2 == 0) {
            document.write(FindSum(tree, 0, N - 1,
                            Q[i][1], Q[i][2], 0)
                 + " ");
        }
        else {
            document.write( -FindSum(tree, 0, N - 1,
                             Q[i][1], Q[i][2], 0)
                 + " ");
        }
    }
}
 
 
</script>
Producción: 

-2 2

 

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 *