给定N个整数的数组arr []和Q个查询,其中每行由两个数字L和R组成,它们表示范围[L,R] ,任务是查找范围[ L,R] 。
例子:
Input: arr[] = {10, 13, 15, 2, 45, 31, 22, 3, 27}, Q[][] = {{2, 5}, {6, 8}, {1, 7}, {4, 8}, {0, 5}}
Output: 27 46 -33 60 24
Explanation:
Result of query {2, 5} is 27 ( 15 – 2 + 45 – 31)
Result of query {6, 8} is 46 ( 22 – 3 + 27)
Result of query {1, 7} is -33 ( 13 – 15 + 2 – 45 + 31 – 22 + 3)
Result of query {4, 8} is 60 ( 45 – 31 + 22 – 3 + 27)
Result of query {0, 5} is 24 ( 10 – 13 + 15 – 2 + 45 – 31)
Input: arr[] = {1, 1, 1, 1, 1, 1, 1, 1, 1}, Q[] = {{2, 5}, {6, 8}, {1, 7}, {4, 8}, {0, 5}}
Output: 0 1 1 1 0
天真的方法:天真的想法是针对每个查询从索引L迭代到R ,并找到交替添加和减去数组元素的值,并在执行操作后打印该值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Structure to represent a range query
struct Query {
int L, R;
};
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L, R]
int findResultUtil(int arr[],
int L, int R)
{
int result = 0;
// A boolean variable flag to
// alternatively add and subtract
bool flag = false;
// Iterate from [L, R]
for (int i = L; i <= R; i++) {
// if flag is false, then
// add & toggle the flag
if (flag == false) {
result = result + arr[i];
flag = true;
}
// if flag is true subtract
// and toggle the flag
else {
result = result - arr[i];
flag = false;
}
}
// Return the final result
return result;
}
// Function to find the value
// for each query
void findResult(int arr[], int n,
Query q[], int m)
{
// Iterate for each query
for (int i = 0; i < m; i++) {
cout << findResultUtil(arr,
q[i].L,
q[i].R)
<< " ";
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = sizeof(arr) / sizeof(arr[0]);
// Given Queries
Query q[] = { { 2, 5 }, { 6, 8 },
{ 1, 7 }, { 4, 8 },
{ 0, 5 } };
int m = sizeof(q) / sizeof(q[0]);
// Function Call
findResult(arr, n, q, m);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Structure to represent a range query
static class Query
{
int L, R;
public Query(int l, int r)
{
super();
L = l;
R = r;
}
};
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L, R]
static int findResultUtil(int arr[],
int L, int R)
{
int result = 0;
// A boolean variable flag to
// alternatively add and subtract
boolean flag = false;
// Iterate from [L, R]
for(int i = L; i <= R; i++)
{
// If flag is false, then
// add & toggle the flag
if (flag == false)
{
result = result + arr[i];
flag = true;
}
// If flag is true subtract
// and toggle the flag
else
{
result = result - arr[i];
flag = false;
}
}
// Return the final result
return result;
}
// Function to find the value
// for each query
static void findResult(int arr[], int n,
Query q[], int m)
{
// Iterate for each query
for(int i = 0; i < m; i++)
{
System.out.print(findResultUtil(arr,
q[i].L, q[i].R) + " ");
}
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = arr.length;
// Given Queries
Query q[] = { new Query(2, 5), new Query(6, 8),
new Query(1, 7), new Query(4, 8),
new Query(0, 5) };
int m = q.length;
// Function call
findResult(arr, n, q, m);
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program for the above approach
# Function to find the result of
# alternatively adding and subtracting
# elements in the range [L, R]
def findResultUtil(arr, L, R):
result = 0
# A boolean variable flag to
# alternatively add and subtract
flag = False
# Iterate from [L, R]
for i in range(L, R + 1):
# If flag is False, then
# add & toggle the flag
if (flag == False):
result = result + arr[i]
flag = True
# If flag is True subtract
# and toggle the flag
else:
result = result - arr[i]
flag = False
# Return the final result
return result
# Function to find the value
# for each query
def findResult(arr, n, q, m):
# Iterate for each query
for i in range(m):
print(findResultUtil(arr,
q[i][0],
q[i][1]),
end = " ")
# Driver Code
if __name__ == '__main__':
# Given array
arr = [ 10, 13, 15, 2, 45,
31, 22, 3, 27 ]
n = len(arr)
# Given Queries
q = [ [ 2, 5 ], [ 6, 8 ],
[ 1, 7 ], [ 4, 8 ],
[ 0, 5 ] ]
m = len(q)
# Function Call
findResult(arr, n, q, m)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// Structure to represent a range query
class Query
{
public int L, R;
public Query(int l, int r)
{
L = l;
R = r;
}
};
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L, R]
static int findResultUtil(int []arr,
int L, int R)
{
int result = 0;
// A bool variable flag to
// alternatively add and subtract
bool flag = false;
// Iterate from [L, R]
for(int i = L; i <= R; i++)
{
// If flag is false, then
// add & toggle the flag
if (flag == false)
{
result = result + arr[i];
flag = true;
}
// If flag is true subtract
// and toggle the flag
else
{
result = result - arr[i];
flag = false;
}
}
// Return the readonly result
return result;
}
// Function to find the value
// for each query
static void findResult(int []arr, int n,
Query []q, int m)
{
// Iterate for each query
for(int i = 0; i < m; i++)
{
Console.Write(findResultUtil(arr,
q[i].L, q[i].R) + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = arr.Length;
// Given Queries
Query []q = { new Query(2, 5), new Query(6, 8),
new Query(1, 7), new Query(4, 8),
new Query(0, 5) };
int m = q.Length;
// Function call
findResult(arr, n, q, m);
}
}
// This code is contributed by gauravrajput1
CPP
// C++ program for the above approach
#include
using namespace std;
// Structure to represent a query
struct Query {
int L, R;
};
// This function fills the Prefix Array
void fillPrefixArray(int arr[], int n,
int prefixArray[])
{
// Initialise the prefix array
prefixArray[0] = arr[0];
// Iterate all the element of arr[]
// and update the prefix array
for (int i = 1; i < n; i++) {
// If n is even then, add the
// previous value of prefix array
// with the current value of arr
if (i % 2 == 0) {
prefixArray[i]
= prefixArray[i - 1]
+ arr[i];
}
// if n is odd, then subtract
// the previous value of prefix
// Array from current value
else {
prefixArray[i]
= prefixArray[i - 1]
- arr[i];
}
}
}
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L< R]
int findResultUtil(int prefixArray[],
int L, int R)
{
int result;
// Case 1 : when L is zero
if (L == 0) {
result = prefixArray[R];
}
// Case 2 : When L is non zero
else {
result = prefixArray[R]
- prefixArray[L - 1];
}
// If L is odd means range starts from
// odd position multiply result by -1
if (L & 1) {
result = result * (-1);
}
// Return the final result
return result;
}
// Function to find the sum of all
// alternative add and subtract
// between ranges [L, R]
void findResult(int arr[], int n,
Query q[], int m)
{
// Declare prefix array
int prefixArray[n];
// Function Call to fill prefix arr[]
fillPrefixArray(arr, n, prefixArray);
// Iterate for each query
for (int i = 0; i < m; i++) {
cout << findResultUtil(prefixArray,
q[i].L,
q[i].R)
<< " ";
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = sizeof(arr) / sizeof(arr[0]);
// Given Queries
Query q[] = { { 2, 5 }, { 6, 8 },
{ 1, 7 }, { 4, 8 },
{ 0, 5 } };
int m = sizeof(q) / sizeof(q[0]);
// Function Call
findResult(arr, n, q, m);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Structure to represent a query
static class Query
{
int L, R;
public Query(int l, int r)
{
super();
L = l;
R = r;
}
};
// This function fills the Prefix Array
static void fillPrefixArray(int arr[], int n,
int prefixArray[])
{
// Initialise the prefix array
prefixArray[0] = arr[0];
// Iterate all the element of arr[]
// and update the prefix array
for (int i = 1; i < n; i++)
{
// If n is even then, add the
// previous value of prefix array
// with the current value of arr
if (i % 2 == 0)
{
prefixArray[i] = prefixArray[i - 1] +
arr[i];
}
// if n is odd, then subtract
// the previous value of prefix
// Array from current value
else
{
prefixArray[i] = prefixArray[i - 1] -
arr[i];
}
}
}
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L< R]
static int findResultUtil(int prefixArray[],
int L, int R)
{
int result;
// Case 1 : when L is zero
if (L == 0)
{
result = prefixArray[R];
}
// Case 2 : When L is non zero
else
{
result = prefixArray[R] -
prefixArray[L - 1];
}
// If L is odd means range starts from
// odd position multiply result by -1
if (L % 2 == 1)
{
result = result * (-1);
}
// Return the final result
return result;
}
// Function to find the sum of all
// alternative add and subtract
// between ranges [L, R]
static void findResult(int arr[], int n,
Query q[], int m)
{
// Declare prefix array
int []prefixArray = new int[n];
// Function Call to fill prefix arr[]
fillPrefixArray(arr, n, prefixArray);
// Iterate for each query
for (int i = 0; i < m; i++)
{
System.out.print(findResultUtil(
prefixArray, q[i].L,
q[i].R) + " ");
}
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = arr.length;
// Given Queries
Query q[] = {new Query( 2, 5 ), new Query( 6, 8 ),
new Query( 1, 7 ), new Query( 4, 8 ),
new Query( 0, 5 )};
int m = q.length;
// Function Call
findResult(arr, n, q, m);
}
}
// This code is contributed by PrinciRaj1992
C#
// C# program for the above approach
using System;
class GFG{
// Structure to represent a query
class Query
{
public int L, R;
public Query(int l, int r)
{
L = l;
R = r;
}
};
// This function fills the Prefix Array
static void fillPrefixArray(int []arr, int n,
int []prefixArray)
{
// Initialise the prefix array
prefixArray[0] = arr[0];
// Iterate all the element of []arr
// and update the prefix array
for (int i = 1; i < n; i++)
{
// If n is even then, add the
// previous value of prefix array
// with the current value of arr
if (i % 2 == 0)
{
prefixArray[i] = prefixArray[i - 1] +
arr[i];
}
// if n is odd, then subtract
// the previous value of prefix
// Array from current value
else
{
prefixArray[i] = prefixArray[i - 1] -
arr[i];
}
}
}
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L< R]
static int findResultUtil(int []prefixArray,
int L, int R)
{
int result;
// Case 1 : when L is zero
if (L == 0)
{
result = prefixArray[R];
}
// Case 2 : When L is non zero
else
{
result = prefixArray[R] -
prefixArray[L - 1];
}
// If L is odd means range starts from
// odd position multiply result by -1
if (L % 2 == 1)
{
result = result * (-1);
}
// Return the readonly result
return result;
}
// Function to find the sum of all
// alternative add and subtract
// between ranges [L, R]
static void findResult(int []arr, int n,
Query []q, int m)
{
// Declare prefix array
int []prefixArray = new int[n];
// Function Call to fill prefix []arr
fillPrefixArray(arr, n, prefixArray);
// Iterate for each query
for (int i = 0; i < m; i++)
{
Console.Write(findResultUtil(
prefixArray, q[i].L,
q[i].R) + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = arr.Length;
// Given Queries
Query []q = {new Query( 2, 5 ), new Query( 6, 8 ),
new Query( 1, 7 ), new Query( 4, 8 ),
new Query( 0, 5 )};
int m = q.Length;
// Function Call
findResult(arr, n, q, m);
}
}
// This code is contributed by Rohit_ranjan
27 46 -33 60 24
时间复杂度: O(N * Q)
辅助空间: O(1)
高效的方法:高效的方法是使用Prefix Sum Array解决上述问题。步骤如下:
- 将前缀数组的第一个元素(例如pre [] )初始化为arr []的第一个元素。
- 从1到N-1遍历索引,并从pre [i-1]中交替添加和减去arr [i]的元素,并将其存储在pre [i]中以构成前缀数组。
- 现在,遍历每个查询从1到Q ,并根据以下情况查找结果:
- 情况1:如果L为零,则结果为pre [R] 。
- 情况2:如果L不为零,则使用以下公式查找结果:
result = Query(L, R) = pre[R] – pre[L - 1]
- 如果L为奇数,则将上述结果乘以-1 。
下面是上述方法的实现:
CPP
// C++ program for the above approach
#include
using namespace std;
// Structure to represent a query
struct Query {
int L, R;
};
// This function fills the Prefix Array
void fillPrefixArray(int arr[], int n,
int prefixArray[])
{
// Initialise the prefix array
prefixArray[0] = arr[0];
// Iterate all the element of arr[]
// and update the prefix array
for (int i = 1; i < n; i++) {
// If n is even then, add the
// previous value of prefix array
// with the current value of arr
if (i % 2 == 0) {
prefixArray[i]
= prefixArray[i - 1]
+ arr[i];
}
// if n is odd, then subtract
// the previous value of prefix
// Array from current value
else {
prefixArray[i]
= prefixArray[i - 1]
- arr[i];
}
}
}
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L< R]
int findResultUtil(int prefixArray[],
int L, int R)
{
int result;
// Case 1 : when L is zero
if (L == 0) {
result = prefixArray[R];
}
// Case 2 : When L is non zero
else {
result = prefixArray[R]
- prefixArray[L - 1];
}
// If L is odd means range starts from
// odd position multiply result by -1
if (L & 1) {
result = result * (-1);
}
// Return the final result
return result;
}
// Function to find the sum of all
// alternative add and subtract
// between ranges [L, R]
void findResult(int arr[], int n,
Query q[], int m)
{
// Declare prefix array
int prefixArray[n];
// Function Call to fill prefix arr[]
fillPrefixArray(arr, n, prefixArray);
// Iterate for each query
for (int i = 0; i < m; i++) {
cout << findResultUtil(prefixArray,
q[i].L,
q[i].R)
<< " ";
}
}
// Driver Code
int main()
{
// Given array
int arr[] = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = sizeof(arr) / sizeof(arr[0]);
// Given Queries
Query q[] = { { 2, 5 }, { 6, 8 },
{ 1, 7 }, { 4, 8 },
{ 0, 5 } };
int m = sizeof(q) / sizeof(q[0]);
// Function Call
findResult(arr, n, q, m);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Structure to represent a query
static class Query
{
int L, R;
public Query(int l, int r)
{
super();
L = l;
R = r;
}
};
// This function fills the Prefix Array
static void fillPrefixArray(int arr[], int n,
int prefixArray[])
{
// Initialise the prefix array
prefixArray[0] = arr[0];
// Iterate all the element of arr[]
// and update the prefix array
for (int i = 1; i < n; i++)
{
// If n is even then, add the
// previous value of prefix array
// with the current value of arr
if (i % 2 == 0)
{
prefixArray[i] = prefixArray[i - 1] +
arr[i];
}
// if n is odd, then subtract
// the previous value of prefix
// Array from current value
else
{
prefixArray[i] = prefixArray[i - 1] -
arr[i];
}
}
}
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L< R]
static int findResultUtil(int prefixArray[],
int L, int R)
{
int result;
// Case 1 : when L is zero
if (L == 0)
{
result = prefixArray[R];
}
// Case 2 : When L is non zero
else
{
result = prefixArray[R] -
prefixArray[L - 1];
}
// If L is odd means range starts from
// odd position multiply result by -1
if (L % 2 == 1)
{
result = result * (-1);
}
// Return the final result
return result;
}
// Function to find the sum of all
// alternative add and subtract
// between ranges [L, R]
static void findResult(int arr[], int n,
Query q[], int m)
{
// Declare prefix array
int []prefixArray = new int[n];
// Function Call to fill prefix arr[]
fillPrefixArray(arr, n, prefixArray);
// Iterate for each query
for (int i = 0; i < m; i++)
{
System.out.print(findResultUtil(
prefixArray, q[i].L,
q[i].R) + " ");
}
}
// Driver Code
public static void main(String[] args)
{
// Given array
int arr[] = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = arr.length;
// Given Queries
Query q[] = {new Query( 2, 5 ), new Query( 6, 8 ),
new Query( 1, 7 ), new Query( 4, 8 ),
new Query( 0, 5 )};
int m = q.length;
// Function Call
findResult(arr, n, q, m);
}
}
// This code is contributed by PrinciRaj1992
C#
// C# program for the above approach
using System;
class GFG{
// Structure to represent a query
class Query
{
public int L, R;
public Query(int l, int r)
{
L = l;
R = r;
}
};
// This function fills the Prefix Array
static void fillPrefixArray(int []arr, int n,
int []prefixArray)
{
// Initialise the prefix array
prefixArray[0] = arr[0];
// Iterate all the element of []arr
// and update the prefix array
for (int i = 1; i < n; i++)
{
// If n is even then, add the
// previous value of prefix array
// with the current value of arr
if (i % 2 == 0)
{
prefixArray[i] = prefixArray[i - 1] +
arr[i];
}
// if n is odd, then subtract
// the previous value of prefix
// Array from current value
else
{
prefixArray[i] = prefixArray[i - 1] -
arr[i];
}
}
}
// Function to find the result of
// alternatively adding and subtracting
// elements in the range [L< R]
static int findResultUtil(int []prefixArray,
int L, int R)
{
int result;
// Case 1 : when L is zero
if (L == 0)
{
result = prefixArray[R];
}
// Case 2 : When L is non zero
else
{
result = prefixArray[R] -
prefixArray[L - 1];
}
// If L is odd means range starts from
// odd position multiply result by -1
if (L % 2 == 1)
{
result = result * (-1);
}
// Return the readonly result
return result;
}
// Function to find the sum of all
// alternative add and subtract
// between ranges [L, R]
static void findResult(int []arr, int n,
Query []q, int m)
{
// Declare prefix array
int []prefixArray = new int[n];
// Function Call to fill prefix []arr
fillPrefixArray(arr, n, prefixArray);
// Iterate for each query
for (int i = 0; i < m; i++)
{
Console.Write(findResultUtil(
prefixArray, q[i].L,
q[i].R) + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
// Given array
int []arr = { 10, 13, 15, 2, 45,
31, 22, 3, 27 };
int n = arr.Length;
// Given Queries
Query []q = {new Query( 2, 5 ), new Query( 6, 8 ),
new Query( 1, 7 ), new Query( 4, 8 ),
new Query( 0, 5 )};
int m = q.Length;
// Function Call
findResult(arr, n, q, m);
}
}
// This code is contributed by Rohit_ranjan
输出:
27 46 -33 60 24
时间复杂度: O(N + Q)
辅助空间: O(N)