给定一个由N 个整数组成的数组arr[]和一个由(L, R, K)形式的查询组成的矩阵Q[][] ,每个查询的任务是计算范围[ ]中数组元素的总和L, R]存在于索引(基于 0 的索引)处,该索引是K和的倍数
例子:
Input: arr[]={1, 2, 3, 4, 5, 6}, Q[][]={{2, 5, 2}, {0, 5, 1}}
Output:
8
21
Explanation:
Query1: Indexes (2, 4) are multiple of K(= 2) from the range [2, 5]. Therefore, required Sum = 3+5 = 8.
Query2: Since all indices are a multiple of K(= 1), therefore, the required sum from the range [0, 5] = 1 + 2 + 3 + 4 + 5 + 6 = 21
Input: arr[]={4, 3, 5, 1, 9}, Q[][]={{1, 4, 1}, {3, 4, 3}}
Output:
18
1
方法:该问题可以使用Prefix Sum Array 和Range sum 查询技术解决。请按照以下步骤解决问题:
- 初始化一个大小为prefixSum[][]的矩阵,使得prefixSum[i][j]存储索引中存在的元素的总和,这些元素是i到第j个索引的倍数。
- 遍历数组并预先计算前缀和。
- 遍历每个查询,打印prefixSum[K][R] – prefixSum[K][L – 1] 的结果。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above appoach
#include
using namespace std;
// Structure of a Query
struct Node {
int L;
int R;
int K;
};
// Function to calculate the sum of array
// elements at indices from range [L, R]
// which are multiples of K for each query
int kMultipleSum(int arr[], Node Query[],
int N, int Q)
{
// Stores Prefix Sum
int prefixSum[N + 1][N];
// prefixSum[i][j] : Stores the sum from
// indices [0, j] which are multiples of i
for (int i = 1; i <= N; i++) {
prefixSum[i][0] = arr[0];
for (int j = 0; j < N; j++) {
// If index j is a multiple of i
if (j % i == 0) {
// Compute prefix sum
prefixSum[i][j]
= arr[j] + prefixSum[i][j - 1];
}
// Otherwise
else {
prefixSum[i][j]
= prefixSum[i][j - 1];
}
}
}
// Traverse each query
for (int i = 0; i < Q; i++) {
// Sum of all indices upto R which
// are a multiple of K
int last
= prefixSum[Query[i].K][Query[i].R];
int first;
// Sum of all indices upto L - 1 which
// are a multiple of K
if (Query[i].L == 0) {
first
= prefixSum[Query[i].K][Query[i].L];
}
else {
first
= prefixSum[Query[i].K][Query[i].L - 1];
}
// Calculate the difference
cout << last - first << endl;
}
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int N = sizeof(arr) / sizeof(arr[0]);
int Q = 2;
Node Query[Q];
Query[0].L = 2, Query[0].R = 5, Query[0].K = 2;
Query[1].L = 3, Query[1].R = 5, Query[1].K = 5;
kMultipleSum(arr, Query, N, Q);
}
Java
// Java program to implement
// the above appoach
import java.util.*;
class GFG{
// Structure of a Query
static class Node
{
int L;
int R;
int K;
};
// Function to calculate the sum of array
// elements at indices from range [L, R]
// which are multiples of K for each query
static void kMultipleSum(int arr[], Node Query[],
int N, int Q)
{
// Stores Prefix Sum
int prefixSum[][] = new int[N + 1][N];
// prefixSum[i][j] : Stores the sum from
// indices [0, j] which are multiples of i
for(int i = 1; i <= N; i++)
{
prefixSum[i][0] = arr[0];
for(int j = 0; j < N; j++)
{
// If index j is a multiple of i
if (j % i == 0)
{
// Compute prefix sum
if (j != 0)
prefixSum[i][j] = arr[j] +
prefixSum[i][j - 1];
}
// Otherwise
else
{
prefixSum[i][j] = prefixSum[i][j - 1];
}
}
}
// Traverse each query
for(int i = 0; i < Q; i++)
{
// Sum of all indices upto R which
// are a multiple of K
int last = prefixSum[Query[i].K][Query[i].R];
int first;
// Sum of all indices upto L - 1 which
// are a multiple of K
if (Query[i].L == 0)
{
first = prefixSum[Query[i].K][Query[i].L];
}
else
{
first = prefixSum[Query[i].K][Query[i].L - 1];
}
// Calculate the difference
System.out.print(last - first + "\n");
}
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int N = arr.length;
int Q = 2;
Node Query[] = new Node[Q];
for(int i = 0; i < Q; i++)
Query[i] = new Node();
Query[0].L = 2;
Query[0].R = 5;
Query[0].K = 2;
Query[1].L = 3;
Query[1].R = 5;
Query[1].K = 5;
kMultipleSum(arr, Query, N, Q);
}
}
// This code is contributed by 29AjayKumar
C#
// C# program to implement
// the above appoach
using System;
class GFG{
// Structure of a Query
class Node
{
public int L;
public int R;
public int K;
};
// Function to calculate the sum of array
// elements at indices from range [L, R]
// which are multiples of K for each query
static void kMultipleSum(int []arr, Node []Query,
int N, int Q)
{
// Stores Prefix Sum
int [,]prefixSum = new int[N + 1, N];
// prefixSum[i,j] : Stores the sum from
// indices [0, j] which are multiples of i
for(int i = 1; i <= N; i++)
{
prefixSum[i, 0] = arr[0];
for(int j = 0; j < N; j++)
{
// If index j is a multiple of i
if (j % i == 0)
{
// Compute prefix sum
if (j != 0)
prefixSum[i, j] = arr[j] +
prefixSum[i, j - 1];
}
// Otherwise
else
{
prefixSum[i, j] = prefixSum[i, j - 1];
}
}
}
// Traverse each query
for(int i = 0; i < Q; i++)
{
// Sum of all indices upto R which
// are a multiple of K
int last = prefixSum[Query[i].K,Query[i].R];
int first;
// Sum of all indices upto L - 1 which
// are a multiple of K
if (Query[i].L == 0)
{
first = prefixSum[Query[i].K,Query[i].L];
}
else
{
first = prefixSum[Query[i].K,Query[i].L - 1];
}
// Calculate the difference
Console.Write(last - first + "\n");
}
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 1, 2, 3, 4, 5, 6 };
int N = arr.Length;
int Q = 2;
Node []Query = new Node[Q];
for(int i = 0; i < Q; i++)
Query[i] = new Node();
Query[0].L = 2;
Query[0].R = 5;
Query[0].K = 2;
Query[1].L = 3;
Query[1].R = 5;
Query[1].K = 5;
kMultipleSum(arr, Query, N, Q);
}
}
// This code is contributed by 29AjayKumar
8
6
时间复杂度: O(N 2 + O(Q)),计算前缀和数组需要O(N 2 ) 计算复杂度,每个查询需要O(1) 计算复杂度。
辅助空间: O(N 2 )