📌  相关文章
📜  基于给定条件的范围求和查询

📅  最后修改于: 2021-09-06 06:32:36             🧑  作者: Mango

给定一个由N 个整数组成的数组arr[]和由{m, a, b}形式的Q 个查询组成的矩阵Queries[][] 。对于每个查询,任务是根据以下条件找到数组元素的总和:

  • 如果 m = 1:[a, b]范围内数组元素的总和。
  • 如果 m = 2:将数组元素按升序重新排列,求新数组中[a, b]范围内元素的总和。

例子:

朴素方法:思想是遍历给定的查询并根据给定的条件找到所有元素的总和:

  1. 根据给定的 m 选择数组,如果m 等于 1,则选择原始数组,否则选择另一个数组,其中数组arr[] 的所有元素都已排序。
  2. 现在计算范围[a, b]之间数组的总和。
  3. 在范围上迭代一个循环以找到总和。
  4. 打印每个查询的总和。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the sum
// between the given range as per
// value of m
int range_sum(vector v, int a,
              int b)
{
    // Stores the sum
    int sum = 0;
 
    // Loop to calculate the sum
    for (int i = a - 1; i < b; i++) {
        sum += v[i];
    }
 
    // Return sum
    return sum;
}
 
// Function to find the sum of elements
// for each query
void findSum(vector& v1, int q,
             int Queries[][3])
{
    // Take a dummy vector
    vector v2;
 
    // Size of vector
    int n = sizeof(v1) / sizeof(int);
 
    // Copying the elements into
    // dummy vector
    for (int i = 0; i < n; i++) {
        v2.push_back(v1[i]);
    }
 
    // Sort the dummy vector
    sort(v2.begin(), v2.end());
 
    // Performs operations
    for (int i = 0; i < q; i++) {
 
        int m = Queries[i][0];
        int a = Queries[i][1];
        int b = Queries[i][2];
 
        if (m == 1) {
 
            // Function Call to find sum
            cout << range_sum(v1, a, b)
                 << ' ';
        }
        else if (m == 2) {
 
            // Function Call to find sum
            cout << range_sum(v2, a, b)
                 << ' ';
        }
    }
}
 
// Driver Code
int main()
{
    // Given arr[]
    vector arr = { 6, 4, 2, 7, 2, 7 };
 
    int Q = 1;
 
    // Given Queries
    int Queries[][3] = { { 2, 3, 6 } };
 
    // Function Call
    findSum(arr, Q, Queries);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to calculate the sum
// between the given range as per
// value of m
static int range_sum(Vector v, int a,
                                        int b)
{
     
    // Stores the sum
    int sum = 0;
 
    // Loop to calculate the sum
    for(int i = a - 1; i < b; i++)
    {
        sum += v.get(i);
    }
 
    // Return sum
    return sum;
}
 
static int range_sum(int []v, int a,
                     int b)
{
     
    // Stores the sum
    int sum = 0;
     
    // Loop to calculate the sum
    for(int i = a - 1; i < b; i++)
    {
        sum += v[i];
    }
     
    // Return sum
    return sum;
}
 
// Function to find the sum of elements
// for each query
static void findSum(int []v1, int q,
                    int Queries[][])
{
     
    // Take a dummy vector
    Vector v2 = new Vector();
 
    // Size of vector
    int n = v1.length;
 
    // Copying the elements into
    // dummy vector
    for(int i = 0; i < n; i++)
    {
        v2.add(v1[i]);
    }
 
    // Sort the dummy vector
    Collections.sort(v2);
 
    // Performs operations
    for(int i = 0; i < q; i++)
    {
        int m = Queries[i][0];
        int a = Queries[i][1];
        int b = Queries[i][2];
 
        if (m == 1)
        {
             
            // Function call to find sum
            System.out.print(range_sum(
                v1, a, b) + " ");
        }
        else if (m == 2)
        {
 
            // Function call to find sum
            System.out.print(range_sum(
                v2, a, b) + " ");
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given arr[]
    int []arr = { 6, 4, 2, 7, 2, 7 };
 
    int Q = 1;
 
    // Given Queries
    int Queries[][] = { { 2, 3, 6 } };
 
    // Function call
    findSum(arr, Q, Queries);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program for the above approach
 
# Function to calculate the sum
# between the given range as per
# value of m
def range_sum(v, a, b):
 
    # Stores the sum
    Sum = 0
  
    # Loop to calculate the sum
    for i in range(a - 1, b):
        Sum += v[i]
  
    # Return sum
    return Sum
  
# Function to find the sum of elements
# for each query
def findSum(v1, q, Queries):
 
    # Take a dummy vector
    v2 = []
  
    # Size of vector
    n = len(v1)
  
    # Copying the elements into
    # dummy vector
    for i in range(n):
        v2.append(v1[i])
  
    # Sort the dummy vector
    v2.sort()
  
    # Performs operations
    for i in range(q):
        m = Queries[i][0]
        a = Queries[i][1]
        b = Queries[i][2]
  
        if (m == 1):
  
            # Function call to find sum
            print(range_sum(v1, a, b), end = " ")
             
        elif (m == 2):
  
            # Function call to find sum
            print(range_sum(v2, a, b), end = " ")
 
# Driver code
 
# Given arr[]
arr = [ 6, 4, 2, 7, 2, 7 ]
  
Q = 1
  
# Given Queries
Queries = [ [ 2, 3, 6 ] ]
  
# Function call
findSum(arr, Q, Queries)
 
# This code is contributed divyeshrabadiya07


C#
// C# program for the above approach
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
 
class GFG{
     
// Function to calculate the sum
// between the given range as per
// value of m
static int range_sum(ArrayList v, int a,
                                  int b)
{
     
    // Stores the sum
    int sum = 0;
 
    // Loop to calculate the sum
    for(int i = a - 1; i < b; i++)
    {
        sum += (int)v[i];
    }
 
    // Return sum
    return sum;
}
 
// Function to find the sum of elements
// for each query
static void findSum(ArrayList v1, int q,
                    int [,]Queries)
{
     
    // Take a dummy vector
    ArrayList v2 = new ArrayList();
 
    // Size of vector
    int n = v1.Count;
 
    // Copying the elements into
    // dummy vector
    for(int i = 0; i < n; i++)
    {
        v2.Add(v1[i]);
    }
 
    // Sort the dummy vector
    v2.Sort();
 
    // Performs operations
    for(int i = 0; i < q; i++)
    {
        int m = Queries[i, 0];
        int a = Queries[i, 1];
        int b = Queries[i, 2];
     
        if (m == 1)
        {
             
            // Function call to find sum
            Console.Write(range_sum(v1, a, b));
            Console.Write(' ');
        }
        else if (m == 2)
        {
             
            // Function call to find sum
            Console.Write(range_sum(v2, a, b));
            Console.Write(' ');
        }
    }
}
 
// Driver Code
public static void Main(string[] args)
{
     
    // Given arr[]
    ArrayList arr=new ArrayList(){ 6, 4, 2,
                                   7, 2, 7 };
 
    int Q = 1;
 
    // Given Queries
    int [,]Queries = { { 2, 3, 6 } };
 
    // Function call
    findSum(arr, Q, Queries);
}
}
 
// This code is contributed by rutvik_56


C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the sum
// between the given range as per
// value of m
int range_sum(vector& arr, int a,
              int b)
{
    // Stores the sum
    int sum = 0;
 
    // Condition for a to print the
    // sum between ranges [a, b]
    if (a - 2 < 0)
        sum = arr[b - 1];
    else
        sum = arr[b - 1] - arr[a - 2];
 
    // Return sum
    return sum;
}
 
// Function to precalculate the sum
// of both the vectors
void precompute_sum(vector& arr,
                    vector& brr)
{
    int N = (int)arr.size();
 
    // Make Prefix sum array
    for (int i = 1; i <= N; i++) {
        arr[i] = arr[i] + arr[i - 1];
        brr[i] = brr[i] + brr[i - 1];
    }
}
 
// Function to compute the result
// for each query
void find_sum(vector& arr, int q,
              int Queries[][3])
{
    // Take a dummy vector and copy
    // the element of arr in brr
    vector brr(arr);
 
    int N = (int)arr.size();
 
    // Sort the dummy vector
    sort(brr.begin(), brr.end());
 
    // Compute prefix sum of both vectors
    precompute_sum(arr, brr);
 
    // Performs operations
    for (int i = 0; i < q; i++) {
 
        int m = Queries[i][0];
        int a = Queries[i][1];
        int b = Queries[i][2];
 
        if (m == 1) {
 
            // Function Call to find sum
            cout << range_sum(arr, a, b)
                 << ' ';
        }
        else if (m == 2) {
 
            // Function Call to find sum
            cout << range_sum(brr, a, b)
                 << ' ';
        }
    }
}
 
// Driver Code
int main()
{
    // Given arr[]
    vector arr = { 0, 6, 4, 2, 7, 2, 7 };
 
    // Number of queries
    int Q = 1;
 
    // Given queries
    int Queries[][3] = { { 2, 3, 6 } };
 
    // Function Call
    find_sum(arr, Q, Queries);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
     
// Function to calculate the sum
// between the given range as per
// value of m
static int range_sum(int []arr, int a,
                     int b)
{
     
    // Stores the sum
    int sum = 0;
  
    // Condition for a to print the
    // sum between ranges [a, b]
    if (a - 2 < 0)
        sum = arr[b - 1];
    else
        sum = arr[b - 1] - arr[a - 2];
  
    // Return sum
    return sum;
}
  
// Function to precalculate the sum
// of both the vectors
static void precompute_sum(int []arr,
                           int []brr)
{
    int N = (int)arr.length;
  
    // Make Prefix sum array
    for(int i = 1; i < N; i++)
    {
        arr[i] = arr[i] + arr[i - 1];
        brr[i] = brr[i] + brr[i - 1];
    }
}
  
// Function to compute the result
// for each query
static void find_sum(int []arr, int q,
                     int Queries[][])
{
     
    // Take a dummy vector and copy
    // the element of arr in brr
    int []brr = arr.clone();
  
    int N = (int)arr.length;
  
    // Sort the dummy vector
    Arrays.sort(brr);
  
    // Compute prefix sum of both vectors
    precompute_sum(arr, brr);
  
    // Performs operations
    for(int i = 0; i < q; i++)
    {
        int m = Queries[i][0];
        int a = Queries[i][1];
        int b = Queries[i][2];
  
        if (m == 1)
        {
             
            // Function call to find sum
            System.out.print(range_sum(
                arr, a, b) + " ");
        }
        else if (m == 2)
        {
             
            // Function call to find sum
            System.out.print(range_sum(
                brr, a, b) + " ");
        }
    }
}
  
// Driver Code
public static void main(String[] args)
{
     
    // Given arr[]
    int []arr = { 0, 6, 4, 2, 7, 2, 7 };
     
    // Number of queries
    int Q = 1;
  
    // Given queries
    int Queries[][] = { { 2, 3, 6 } };
  
    // Function call
    find_sum(arr, Q, Queries);
}
}
  
// This code is contributed by Amit Katiyar


Python3
# Python3 program for
# the above approach
 
# Function to calculate
# the sum between the
# given range as per value
# of m
def range_sum(arr, a, b):
 
    # Stores the sum
    sum = 0
 
    # Condition for a to
    # print the sum between
    # ranges [a, b]
    if (a - 2 < 0):
        sum = arr[b - 1]
    else:
        sum = (arr[b - 1] -
               arr[a - 2])
 
    # Return sum
    return sum
 
# Function to precalculate
# the sum of both the vectors
def precompute_sum(arr, brr):
 
    N = len(arr)
 
    # Make Prefix sum array
    for i in range(1, N):
        arr[i] = arr[i] + arr[i - 1]
        brr[i] = brr[i] + brr[i - 1]
 
# Function to compute
# the result for each query
def find_sum(arr, q, Queries):
 
    # Take a dummy vector
    # and copy the element
    # of arr in brr
    brr = arr.copy()
 
    N = len(arr)
 
    # Sort the dummy vector
    brr.sort()
 
    # Compute prefix sum of
    # both vectors
    precompute_sum(arr, brr)
 
    # Performs operations
    for i in range(q):
 
        m = Queries[i][0]
        a = Queries[i][1]
        b = Queries[i][2]
 
        if (m == 1):
 
            # Function Call to
            # find sum
            print (range_sum(arr,
                             a, b),
                   end = ' ')
         
        elif (m == 2):
 
            # Function Call to
            # find sum
            print (range_sum(brr,
                             a, b),
                   end = ' ')
 
# Driver Code
if __name__ == "__main__":
   
    # Given arr[]
    arr = [0, 6, 4,
           2, 7, 2, 7]
 
    # Number of queries
    Q = 1
 
    # Given queries
    Queries = [[2, 3, 6]]
 
    # Function Call
    find_sum(arr, Q, Queries)
 
# This code is contributed by Chitranayal


C#
// C# program for
// the above approach
using System;
class GFG{
     
// Function to calculate the sum
// between the given range as per
// value of m
static int range_sum(int []arr,
                     int a,
                     int b)
{
  // Stores the sum
  int sum = 0;
 
  // Condition for a to print the
  // sum between ranges [a, b]
  if (a - 2 < 0)
    sum = arr[b - 1];
  else
    sum = arr[b - 1] - arr[a - 2];
 
  // Return sum
  return sum;
}
  
// Function to precalculate the sum
// of both the vectors
static void precompute_sum(int []arr,
                           int []brr)
{
  int N = (int)arr.Length;
 
  // Make Prefix sum array
  for(int i = 1; i < N; i++)
  {
    arr[i] = arr[i] + arr[i - 1];
    brr[i] = brr[i] + brr[i - 1];
  }
}
  
// Function to compute the result
// for each query
static void find_sum(int []arr, int q,
                     int [,]Queries)
{   
  // Take a dummy vector and copy
  // the element of arr in brr
  int []brr = new int[arr.Length];
  arr.CopyTo(brr, 0);
 
  int N = (int)arr.Length;
 
  // Sort the dummy vector
  Array.Sort(brr);
 
  // Compute prefix sum of both vectors
  precompute_sum(arr, brr);
 
  // Performs operations
  for(int i = 0; i < q; i++)
  {
    int m = Queries[i, 0];
    int a = Queries[i, 1];
    int b = Queries[i, 2];
 
    if (m == 1)
    {
      // Function call to find sum
      Console.Write(range_sum(
                    arr, a, b) + " ");
    }
    else if (m == 2)
    {
      // Function call to find sum
      Console.Write(range_sum(
                    brr, a, b) + " ");
    }
  }
}
  
// Driver Code
public static void Main(String[] args)
{
  // Given []arr
  int []arr = {0, 6, 4, 2, 7, 2, 7};
 
  // Number of queries
  int Q = 1;
 
  // Given queries
  int [,]Queries = {{2, 3, 6}};
 
  // Function call
  find_sum(arr, Q, Queries);
}
}
 
// This code is contributed by 29AjayKumar


输出:
24





时间复杂度: O(N 2 )
辅助空间: O(N)

高效的方法:可以通过使用前缀和数组减少一个循环来优化上述方法。以下是步骤:

  • 创建另一个数组brr[]以按排序顺序存储给定数组arr[]的元素。
  • 找到数组arr[]brr[]的前缀和。
  • 遍历给定的查询,如果查询的类型为 1,则 [a, b] 范围内元素的总和由下式给出:
  • 如果查询是类型 2,则 [a, b] 范围内元素的总和由下式给出:

下面是上述方法的实现:

C++

// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the sum
// between the given range as per
// value of m
int range_sum(vector& arr, int a,
              int b)
{
    // Stores the sum
    int sum = 0;
 
    // Condition for a to print the
    // sum between ranges [a, b]
    if (a - 2 < 0)
        sum = arr[b - 1];
    else
        sum = arr[b - 1] - arr[a - 2];
 
    // Return sum
    return sum;
}
 
// Function to precalculate the sum
// of both the vectors
void precompute_sum(vector& arr,
                    vector& brr)
{
    int N = (int)arr.size();
 
    // Make Prefix sum array
    for (int i = 1; i <= N; i++) {
        arr[i] = arr[i] + arr[i - 1];
        brr[i] = brr[i] + brr[i - 1];
    }
}
 
// Function to compute the result
// for each query
void find_sum(vector& arr, int q,
              int Queries[][3])
{
    // Take a dummy vector and copy
    // the element of arr in brr
    vector brr(arr);
 
    int N = (int)arr.size();
 
    // Sort the dummy vector
    sort(brr.begin(), brr.end());
 
    // Compute prefix sum of both vectors
    precompute_sum(arr, brr);
 
    // Performs operations
    for (int i = 0; i < q; i++) {
 
        int m = Queries[i][0];
        int a = Queries[i][1];
        int b = Queries[i][2];
 
        if (m == 1) {
 
            // Function Call to find sum
            cout << range_sum(arr, a, b)
                 << ' ';
        }
        else if (m == 2) {
 
            // Function Call to find sum
            cout << range_sum(brr, a, b)
                 << ' ';
        }
    }
}
 
// Driver Code
int main()
{
    // Given arr[]
    vector arr = { 0, 6, 4, 2, 7, 2, 7 };
 
    // Number of queries
    int Q = 1;
 
    // Given queries
    int Queries[][3] = { { 2, 3, 6 } };
 
    // Function Call
    find_sum(arr, Q, Queries);
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
  
class GFG{
     
// Function to calculate the sum
// between the given range as per
// value of m
static int range_sum(int []arr, int a,
                     int b)
{
     
    // Stores the sum
    int sum = 0;
  
    // Condition for a to print the
    // sum between ranges [a, b]
    if (a - 2 < 0)
        sum = arr[b - 1];
    else
        sum = arr[b - 1] - arr[a - 2];
  
    // Return sum
    return sum;
}
  
// Function to precalculate the sum
// of both the vectors
static void precompute_sum(int []arr,
                           int []brr)
{
    int N = (int)arr.length;
  
    // Make Prefix sum array
    for(int i = 1; i < N; i++)
    {
        arr[i] = arr[i] + arr[i - 1];
        brr[i] = brr[i] + brr[i - 1];
    }
}
  
// Function to compute the result
// for each query
static void find_sum(int []arr, int q,
                     int Queries[][])
{
     
    // Take a dummy vector and copy
    // the element of arr in brr
    int []brr = arr.clone();
  
    int N = (int)arr.length;
  
    // Sort the dummy vector
    Arrays.sort(brr);
  
    // Compute prefix sum of both vectors
    precompute_sum(arr, brr);
  
    // Performs operations
    for(int i = 0; i < q; i++)
    {
        int m = Queries[i][0];
        int a = Queries[i][1];
        int b = Queries[i][2];
  
        if (m == 1)
        {
             
            // Function call to find sum
            System.out.print(range_sum(
                arr, a, b) + " ");
        }
        else if (m == 2)
        {
             
            // Function call to find sum
            System.out.print(range_sum(
                brr, a, b) + " ");
        }
    }
}
  
// Driver Code
public static void main(String[] args)
{
     
    // Given arr[]
    int []arr = { 0, 6, 4, 2, 7, 2, 7 };
     
    // Number of queries
    int Q = 1;
  
    // Given queries
    int Queries[][] = { { 2, 3, 6 } };
  
    // Function call
    find_sum(arr, Q, Queries);
}
}
  
// This code is contributed by Amit Katiyar

蟒蛇3

# Python3 program for
# the above approach
 
# Function to calculate
# the sum between the
# given range as per value
# of m
def range_sum(arr, a, b):
 
    # Stores the sum
    sum = 0
 
    # Condition for a to
    # print the sum between
    # ranges [a, b]
    if (a - 2 < 0):
        sum = arr[b - 1]
    else:
        sum = (arr[b - 1] -
               arr[a - 2])
 
    # Return sum
    return sum
 
# Function to precalculate
# the sum of both the vectors
def precompute_sum(arr, brr):
 
    N = len(arr)
 
    # Make Prefix sum array
    for i in range(1, N):
        arr[i] = arr[i] + arr[i - 1]
        brr[i] = brr[i] + brr[i - 1]
 
# Function to compute
# the result for each query
def find_sum(arr, q, Queries):
 
    # Take a dummy vector
    # and copy the element
    # of arr in brr
    brr = arr.copy()
 
    N = len(arr)
 
    # Sort the dummy vector
    brr.sort()
 
    # Compute prefix sum of
    # both vectors
    precompute_sum(arr, brr)
 
    # Performs operations
    for i in range(q):
 
        m = Queries[i][0]
        a = Queries[i][1]
        b = Queries[i][2]
 
        if (m == 1):
 
            # Function Call to
            # find sum
            print (range_sum(arr,
                             a, b),
                   end = ' ')
         
        elif (m == 2):
 
            # Function Call to
            # find sum
            print (range_sum(brr,
                             a, b),
                   end = ' ')
 
# Driver Code
if __name__ == "__main__":
   
    # Given arr[]
    arr = [0, 6, 4,
           2, 7, 2, 7]
 
    # Number of queries
    Q = 1
 
    # Given queries
    Queries = [[2, 3, 6]]
 
    # Function Call
    find_sum(arr, Q, Queries)
 
# This code is contributed by Chitranayal

C#

// C# program for
// the above approach
using System;
class GFG{
     
// Function to calculate the sum
// between the given range as per
// value of m
static int range_sum(int []arr,
                     int a,
                     int b)
{
  // Stores the sum
  int sum = 0;
 
  // Condition for a to print the
  // sum between ranges [a, b]
  if (a - 2 < 0)
    sum = arr[b - 1];
  else
    sum = arr[b - 1] - arr[a - 2];
 
  // Return sum
  return sum;
}
  
// Function to precalculate the sum
// of both the vectors
static void precompute_sum(int []arr,
                           int []brr)
{
  int N = (int)arr.Length;
 
  // Make Prefix sum array
  for(int i = 1; i < N; i++)
  {
    arr[i] = arr[i] + arr[i - 1];
    brr[i] = brr[i] + brr[i - 1];
  }
}
  
// Function to compute the result
// for each query
static void find_sum(int []arr, int q,
                     int [,]Queries)
{   
  // Take a dummy vector and copy
  // the element of arr in brr
  int []brr = new int[arr.Length];
  arr.CopyTo(brr, 0);
 
  int N = (int)arr.Length;
 
  // Sort the dummy vector
  Array.Sort(brr);
 
  // Compute prefix sum of both vectors
  precompute_sum(arr, brr);
 
  // Performs operations
  for(int i = 0; i < q; i++)
  {
    int m = Queries[i, 0];
    int a = Queries[i, 1];
    int b = Queries[i, 2];
 
    if (m == 1)
    {
      // Function call to find sum
      Console.Write(range_sum(
                    arr, a, b) + " ");
    }
    else if (m == 2)
    {
      // Function call to find sum
      Console.Write(range_sum(
                    brr, a, b) + " ");
    }
  }
}
  
// Driver Code
public static void Main(String[] args)
{
  // Given []arr
  int []arr = {0, 6, 4, 2, 7, 2, 7};
 
  // Number of queries
  int Q = 1;
 
  // Given queries
  int [,]Queries = {{2, 3, 6}};
 
  // Function call
  find_sum(arr, Q, Queries);
}
}
 
// This code is contributed by 29AjayKumar
输出:
19





时间复杂度: O(N*log N)
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live