给定范围内所有无序对与更新查询的乘积之和
给定一个包含N个整数和以下类型的Q个查询的数组A[] ,任务是打印所有更新查询的输出。
- (1, L, R):第一种查询类型,用于查找数组中从索引L到R的所有无序对的乘积之和,其中1 <= L <= R <= N 。
- (2, P, X):第二种查询类型,将数组的第P个整数的值更改为新值X 。
例子:
Input: A[] = {5 7 2 3 1}, Q = 3, Queries[] = [ [1, 1, 3], [2, 2, 5], [1, 2, 5]]
Output:
59
41
Explanation:
Query 1: In the 1st query, the possible pairs in the given range are (5, 7), (5, 2) and (7, 2). So the pairwise product sum will be (5*7) + (5*2) + (7*2) = 35 + 10 + 14 = 59.
Query 2: In the 2nd query, update the 2nd integer to 5, which makes the array as [5, 5, 2, 3, 1].
Query 3: In the 3rd query, the possible pairs in range [2, 5] are (5, 2), (5, 3), (5, 1), (2, 3), (2, 1), and (3, 1). The sum of product of these pairs is 41.
Input: A[] = {7 3 2 1 4 5 8}, Q = 5, Queries[] = [ [1, 1, 6], [2, 2, 4], [1, 2, 5], [2, 3, 8], [1, 4, 7]]
Output: 59
41
6
朴素方法:解决这个问题的简单方法是对于第一种类型的查询,生成给定查询范围内的所有无序对并打印这些对的乘积之和。对于第二种查询,根据给定值更新数组元素。
下面是上述方法的实现:
C++
// C++ Program for the above approach
#include
using namespace std;
// Function to calculate the Pairwise
// Product Sum in range from L to R
void pairwiseProductSum(int a[], int l, int r)
{
int sum = 0;
// Loop to iterate over all possible
// pairs from L to R
for (int j = l - 1; j <= r - 1; j++) {
for (int k = j + 1; k <= r - 1; k++) {
sum += (a[j] * a[k]);
}
}
// Print answer
cout << sum << endl;
}
// Function to update the Array
// element at index P to X
void updateArray(int* a, int p, int x)
{
// Update the value at Pth
// index in the array
a[p - 1] = x;
}
// Function to solve Q queries
void solveQueries(
int* a, int n,
int Q, int query[][3])
{
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i][0] == 1)
pairwiseProductSum(
a, query[i][1], query[i][2]);
// If Query is of type 2
else
updateArray(
a, query[i][1], query[i][2]);
}
}
// Driver Code
int main()
{
int A[] = { 5, 7, 2, 3, 1 };
int N = sizeof(A) / sizeof(int);
int Q = 3;
int query[Q][3] = { { 1, 1, 3 },
{ 2, 2, 5 },
{ 1, 2, 5 } };
solveQueries(A, N, Q, query);
return 0;
}
Java
// Java Program for the above approach
import java.util.*;
class GFG{
// Function to calculate the Pairwise
// Product Sum in range from L to R
static void pairwiseProductSum(int a[], int l, int r)
{
int sum = 0;
// Loop to iterate over all possible
// pairs from L to R
for (int j = l - 1; j <= r - 1; j++) {
for (int k = j + 1; k <= r - 1; k++) {
sum += (a[j] * a[k]);
}
}
// Print answer
System.out.print(sum +"\n");
}
// Function to update the Array
// element at index P to X
static void updateArray(int[] a, int p, int x)
{
// Update the value at Pth
// index in the array
a[p - 1] = x;
}
// Function to solve Q queries
static void solveQueries(
int[] a, int n,
int Q,
int query[][])
{
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i][0] == 1)
pairwiseProductSum(
a, query[i][1], query[i][2]);
// If Query is of type 2
else
updateArray(
a, query[i][1], query[i][2]);
}
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 5, 7, 2, 3, 1 };
int N = A.length;
int Q = 3;
int query[][] = { { 1, 1, 3 },
{ 2, 2, 5 },
{ 1, 2, 5 } };
solveQueries(A, N, Q, query);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python 3 Program for the above approach
# Function to calculate the Pairwise
# Product Sum in range from L to R
def pairwiseProductSum(a, l, r):
sum = 0
# Loop to iterate over all possible
# pairs from L to R
for j in range(l - 1,r,1):
for k in range(j + 1,r,1):
sum += (a[j] * a[k]);
# Print answer
print(sum)
# Function to update the Array
# element at index P to X
def updateArray(a, p, x):
# Update the value at Pth
# index in the array
a[p - 1] = x
# Function to solve Q queries
def solveQueries(a,n,Q,query):
for i in range(Q):
# If Query is of type 1
if (query[i][0] == 1):
pairwiseProductSum(a, query[i][1], query[i][2])
# If Query is of type 2
else:
updateArray(a, query[i][1], query[i][2])
# Driver Code
if __name__ == '__main__':
A = [5, 7, 2, 3, 1]
N = len(A)
Q = 3
query = [[1, 1, 3],[2, 2, 5],[1, 2, 5]]
solveQueries(A, N, Q, query)
# This code is contributed by ipg2016107
C#
//C# code for the above approach
using System;
public class GFG{
// Function to calculate the Pairwise
// Product Sum in range from L to R
static void pairwiseProductSum(int[] a, int l, int r)
{
int sum = 0;
// Loop to iterate over all possible
// pairs from L to R
for (int j = l - 1; j <= r - 1; j++) {
for (int k = j + 1; k <= r - 1; k++) {
sum += (a[j] * a[k]);
}
}
// Print answer
Console.Write(sum +"\n");
}
// Function to update the Array
// element at index P to X
static void updateArray(int[] a, int p, int x)
{
// Update the value at Pth
// index in the array
a[p - 1] = x;
}
// Function to solve Q queries
static void solveQueries(
int[] a, int n,
int Q,
int[][] query)
{
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i][0] == 1)
pairwiseProductSum(
a, query[i][1], query[i][2]);
// If Query is of type 2
else
updateArray(
a, query[i][1], query[i][2]);
}
}
// Driver Code
static public void Main (){
// Code
int[] A = { 5, 7, 2, 3, 1 };
int N = A.Length;
int Q = 3;
int[][] query = {
new int[3]{ 1, 1, 3 },
new int[3]{ 2, 2, 5 },
new int[3] { 1, 2, 5 }
};
solveQueries(A, N, Q, query);
}
}
// This code is contributed by Potta Lokesh
Javascript
C++
Java
// Java Program for the above approach
class GFG{
static final int MAXN = 100000;
// Vector to store fenwick tree
// of the 1st type
static int []bit1 = new int[MAXN];
// Vector to store fenwick tree
// of the 2nd type
static int []bit2 = new int[MAXN];
// Function to update the value
// at idx index in fenwick tree
static void update(int idx, int val, int []bit)
{
while (idx < bit.length) {
bit[idx] += val;
idx += idx & (-idx);
}
}
// Function to return the sum of values
// stored from O to idx index in the
// array using Fenwick Tree
static int query(int idx, int []bit)
{
int res = 0;
while (idx > 0) {
res += bit[idx];
idx -= idx & (-idx);
}
return res;
}
// Function to build the Fenwick
// tree from the a[] Array
static void buildFenwickTree(int a[], int n)
{
for (int i = 1; i <= n; i++) {
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1], bit1);
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1] * a[i - 1], bit2);
}
}
// Function to find the Pairwise
// Product Sum in the range L to R
static void pairwiseProductSum(int a[], int l, int r)
{
int sum, e, q;
// Function call to calculate E
// in the given range
e = query(r, bit1) - query(l - 1, bit1);
e = e * e;
// Function call to calculate E
// in the given range
q = query(r, bit2) - query(l - 1, bit2);
sum = (e - q) / 2;
// Print Answer
System.out.print(sum +"\n");
}
// Function to update the Fenwick
// tree and the array element at
// index P to the new value X
static void updateArray(int[] a, int p, int x)
{
// Function call to update the
// value in 1st Fenwick Tree
update(p, -a[p - 1], bit1);
update(p, x, bit1);
// Function call to update the
// value in 2nd Fenwick Tree
update(p, -a[p - 1] * a[p - 1], bit2);
update(p, x * x, bit2);
a[p - 1] = x;
}
// Function to solve Q queries
static void solveQueries(
int[] a, int n,
int Q, int query[][])
{
// Function Call to build the
// Fenwick Tree
buildFenwickTree(a, n);
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i][0] == 1)
pairwiseProductSum(
a, query[i][1], query[i][2]);
// If Query is of type 2
else
updateArray(
a, query[i][1], query[i][2]);
}
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 5, 7, 2, 3, 1 };
int N = A.length;
int Q = 3;
int query[][] = { { 1, 1, 3 },
{ 2, 2, 5 },
{ 1, 2, 5 } };
solveQueries(A, N, Q, query);
}
}
// This code is contributed by Princi Singh
C#
// C# Program for the above approach
using System;
class GFG {
static int MAXN = 100000;
// Vector to store fenwick tree
// of the 1st type
static int[] bit1 = new int[MAXN];
// Vector to store fenwick tree
// of the 2nd type
static int[] bit2 = new int[MAXN];
// Function to update the value
// at idx index in fenwick tree
static void update(int idx, int val, int[] bit)
{
while (idx < bit.Length) {
bit[idx] += val;
idx += idx & (-idx);
}
}
// Function to return the sum of values
// stored from O to idx index in the
// array using Fenwick Tree
static int query(int idx, int[] bit)
{
int res = 0;
while (idx > 0) {
res += bit[idx];
idx -= idx & (-idx);
}
return res;
}
// Function to build the Fenwick
// tree from the a[] Array
static void buildFenwickTree(int[] a, int n)
{
for (int i = 1; i <= n; i++) {
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1], bit1);
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1] * a[i - 1], bit2);
}
}
// Function to find the Pairwise
// Product Sum in the range L to R
static void pairwiseProductSum(int[] a, int l, int r)
{
int sum, e, q;
// Function call to calculate E
// in the given range
e = query(r, bit1) - query(l - 1, bit1);
e = e * e;
// Function call to calculate E
// in the given range
q = query(r, bit2) - query(l - 1, bit2);
sum = (e - q) / 2;
// Print Answer
Console.WriteLine(sum);
}
// Function to update the Fenwick
// tree and the array element at
// index P to the new value X
static void updateArray(int[] a, int p, int x)
{
// Function call to update the
// value in 1st Fenwick Tree
update(p, -a[p - 1], bit1);
update(p, x, bit1);
// Function call to update the
// value in 2nd Fenwick Tree
update(p, -a[p - 1] * a[p - 1], bit2);
update(p, x * x, bit2);
a[p - 1] = x;
}
// Function to solve Q queries
static void solveQueries(int[] a, int n, int Q,
int[, ] query)
{
// Function Call to build the
// Fenwick Tree
buildFenwickTree(a, n);
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i, 0] == 1)
pairwiseProductSum(a, query[i, 1],
query[i, 2]);
// If Query is of type 2
else
updateArray(a, query[i, 1], query[i, 2]);
}
}
// Driver Code
public static void Main(string[] args)
{
int[] A = { 5, 7, 2, 3, 1 };
int N = A.Length;
int Q = 3;
int[, ] query
= { { 1, 1, 3 }, { 2, 2, 5 }, { 1, 2, 5 } };
solveQueries(A, N, Q, query);
}
}
// This code is contributed by ukasp.
Javascript
Python3
# Python Program for the above approach
MAXN = 100000;
# Vector to store fenwick tree
# of the 1st type
bit1 = [0 for i in range(MAXN)];
# Vector to store fenwick tree
# of the 2nd type
bit2 = [0 for i in range(MAXN)];
# Function to update the value
# at idx index in fenwick tree
def update(idx, val, bit):
while (idx < len(bit)):
bit[idx] += val;
idx += idx & (-idx);
# Function to return the sum of values
# stored from O to idx index in the
# array using Fenwick Tree
def querys(idx, bit):
res = 0;
while (idx > 0):
res += bit[idx];
idx -= idx & (-idx);
return res;
# Function to build the Fenwick
# tree from the a Array
def buildFenwickTree(a, n):
global bit1,bit2
for i in range(1,n+1):
# Function call to update
# the ith element in the
# first Fenwick Tree
update(i, a[i - 1], bit1);
# Function call to update
# the ith element in the
# first Fenwick Tree
update(i, a[i - 1] * a[i - 1], bit2);
# Function to find the Pairwise
# Product Sum in the range L to R
def pairwiseProductSum(a, l, r):
global bit1, bit2;
sum, e, q=0,0,0;
# Function call to calculate E
# in the given range
e = querys(r, bit1) - querys(l - 1, bit1);
e = e * e;
# Function call to calculate E
# in the given range
q = querys(r, bit2) - querys(l - 1, bit2);
sum = (e - q) // 2;
# PrAnswer
print(sum, " ");
# Function to update the Fenwick
# tree and the array element at
# index P to the new value X
def updateArray(a, p, x):
global bit1,bit2
# Function call to update the
# value in 1st Fenwick Tree
update(p, -a[p - 1], bit1);
update(p, x, bit1);
# Function call to update the
# value in 2nd Fenwick Tree
update(p, -a[p - 1] * a[p - 1], bit2);
update(p, x * x, bit2);
a[p - 1] = x;
# Function to solve Q queries
def solveQueries(a, n, Q, query):
# Function Call to build the
# Fenwick Tree
buildFenwickTree(a, n);
for i in range(Q):
# If Query is of type 1
if (query[i][0] == 1):
pairwiseProductSum(a, query[i][1], query[i][2]);
# If Query is of type 2
else:
updateArray(a, query[i][1], query[i][2]);
# Driver Code
if __name__ == '__main__':
A = [5, 7, 2, 3, 1];
N = len(A);
Q = 3;
query = [[1, 1, 3], [2, 2, 5], [1, 2, 5]];
solveQueries(A, N, Q, query);
# This code contributed by shikhasingrajput
59
41
时间复杂度:成对乘积求和查询为O(N 2 ) ,更新查询为O(1) 。
空间复杂度: O(N)
高效方法:使用此处讨论的前缀和技术,可以将每个查询的复杂性降低到O(N) 。
更好的方法:进一步降低复杂性的更好方法是使用基于以下观察的 Fenwick 树:
Given that
(a + b + c)2 = a2 + b2 + c2 + 2*(a*b + b*c + c*a)
Let required Pairwise Product Sum be P
Let E = (a1 + a2 + a3 + a4 … + an)2
=> E = a12 + a22 + … + an2 + 2*(a1*a2 + a1*a3 + ….)
=> E = a12 + a22 + … + an2 + 2*(P)
=> P = ( E – (a12 + a22 + …. + an2) ) / 2
So, P = (E – Q)/2 where Q = (a12 + a22 + …. + an2)
根据以上观察,我们可以维护两棵 Fenwick 树。
- First Fenwick 树将使用更新查询跟踪给定范围内的元素总和。这可用于计算任何给定范围的E。
- 类似地,第二个 Fenwick 树将使用更新查询跟踪给定范围内元素的平方和。这可用于计算任何给定范围的Q。此后, P可以很容易地计算为P = (E – Q)/2 。
下面是上述方法的实现:
C++
Java
// Java Program for the above approach
class GFG{
static final int MAXN = 100000;
// Vector to store fenwick tree
// of the 1st type
static int []bit1 = new int[MAXN];
// Vector to store fenwick tree
// of the 2nd type
static int []bit2 = new int[MAXN];
// Function to update the value
// at idx index in fenwick tree
static void update(int idx, int val, int []bit)
{
while (idx < bit.length) {
bit[idx] += val;
idx += idx & (-idx);
}
}
// Function to return the sum of values
// stored from O to idx index in the
// array using Fenwick Tree
static int query(int idx, int []bit)
{
int res = 0;
while (idx > 0) {
res += bit[idx];
idx -= idx & (-idx);
}
return res;
}
// Function to build the Fenwick
// tree from the a[] Array
static void buildFenwickTree(int a[], int n)
{
for (int i = 1; i <= n; i++) {
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1], bit1);
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1] * a[i - 1], bit2);
}
}
// Function to find the Pairwise
// Product Sum in the range L to R
static void pairwiseProductSum(int a[], int l, int r)
{
int sum, e, q;
// Function call to calculate E
// in the given range
e = query(r, bit1) - query(l - 1, bit1);
e = e * e;
// Function call to calculate E
// in the given range
q = query(r, bit2) - query(l - 1, bit2);
sum = (e - q) / 2;
// Print Answer
System.out.print(sum +"\n");
}
// Function to update the Fenwick
// tree and the array element at
// index P to the new value X
static void updateArray(int[] a, int p, int x)
{
// Function call to update the
// value in 1st Fenwick Tree
update(p, -a[p - 1], bit1);
update(p, x, bit1);
// Function call to update the
// value in 2nd Fenwick Tree
update(p, -a[p - 1] * a[p - 1], bit2);
update(p, x * x, bit2);
a[p - 1] = x;
}
// Function to solve Q queries
static void solveQueries(
int[] a, int n,
int Q, int query[][])
{
// Function Call to build the
// Fenwick Tree
buildFenwickTree(a, n);
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i][0] == 1)
pairwiseProductSum(
a, query[i][1], query[i][2]);
// If Query is of type 2
else
updateArray(
a, query[i][1], query[i][2]);
}
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 5, 7, 2, 3, 1 };
int N = A.length;
int Q = 3;
int query[][] = { { 1, 1, 3 },
{ 2, 2, 5 },
{ 1, 2, 5 } };
solveQueries(A, N, Q, query);
}
}
// This code is contributed by Princi Singh
C#
// C# Program for the above approach
using System;
class GFG {
static int MAXN = 100000;
// Vector to store fenwick tree
// of the 1st type
static int[] bit1 = new int[MAXN];
// Vector to store fenwick tree
// of the 2nd type
static int[] bit2 = new int[MAXN];
// Function to update the value
// at idx index in fenwick tree
static void update(int idx, int val, int[] bit)
{
while (idx < bit.Length) {
bit[idx] += val;
idx += idx & (-idx);
}
}
// Function to return the sum of values
// stored from O to idx index in the
// array using Fenwick Tree
static int query(int idx, int[] bit)
{
int res = 0;
while (idx > 0) {
res += bit[idx];
idx -= idx & (-idx);
}
return res;
}
// Function to build the Fenwick
// tree from the a[] Array
static void buildFenwickTree(int[] a, int n)
{
for (int i = 1; i <= n; i++) {
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1], bit1);
// Function call to update
// the ith element in the
// first Fenwick Tree
update(i, a[i - 1] * a[i - 1], bit2);
}
}
// Function to find the Pairwise
// Product Sum in the range L to R
static void pairwiseProductSum(int[] a, int l, int r)
{
int sum, e, q;
// Function call to calculate E
// in the given range
e = query(r, bit1) - query(l - 1, bit1);
e = e * e;
// Function call to calculate E
// in the given range
q = query(r, bit2) - query(l - 1, bit2);
sum = (e - q) / 2;
// Print Answer
Console.WriteLine(sum);
}
// Function to update the Fenwick
// tree and the array element at
// index P to the new value X
static void updateArray(int[] a, int p, int x)
{
// Function call to update the
// value in 1st Fenwick Tree
update(p, -a[p - 1], bit1);
update(p, x, bit1);
// Function call to update the
// value in 2nd Fenwick Tree
update(p, -a[p - 1] * a[p - 1], bit2);
update(p, x * x, bit2);
a[p - 1] = x;
}
// Function to solve Q queries
static void solveQueries(int[] a, int n, int Q,
int[, ] query)
{
// Function Call to build the
// Fenwick Tree
buildFenwickTree(a, n);
for (int i = 0; i < Q; i++) {
// If Query is of type 1
if (query[i, 0] == 1)
pairwiseProductSum(a, query[i, 1],
query[i, 2]);
// If Query is of type 2
else
updateArray(a, query[i, 1], query[i, 2]);
}
}
// Driver Code
public static void Main(string[] args)
{
int[] A = { 5, 7, 2, 3, 1 };
int N = A.Length;
int Q = 3;
int[, ] query
= { { 1, 1, 3 }, { 2, 2, 5 }, { 1, 2, 5 } };
solveQueries(A, N, Q, query);
}
}
// This code is contributed by ukasp.
Javascript
Python3
# Python Program for the above approach
MAXN = 100000;
# Vector to store fenwick tree
# of the 1st type
bit1 = [0 for i in range(MAXN)];
# Vector to store fenwick tree
# of the 2nd type
bit2 = [0 for i in range(MAXN)];
# Function to update the value
# at idx index in fenwick tree
def update(idx, val, bit):
while (idx < len(bit)):
bit[idx] += val;
idx += idx & (-idx);
# Function to return the sum of values
# stored from O to idx index in the
# array using Fenwick Tree
def querys(idx, bit):
res = 0;
while (idx > 0):
res += bit[idx];
idx -= idx & (-idx);
return res;
# Function to build the Fenwick
# tree from the a Array
def buildFenwickTree(a, n):
global bit1,bit2
for i in range(1,n+1):
# Function call to update
# the ith element in the
# first Fenwick Tree
update(i, a[i - 1], bit1);
# Function call to update
# the ith element in the
# first Fenwick Tree
update(i, a[i - 1] * a[i - 1], bit2);
# Function to find the Pairwise
# Product Sum in the range L to R
def pairwiseProductSum(a, l, r):
global bit1, bit2;
sum, e, q=0,0,0;
# Function call to calculate E
# in the given range
e = querys(r, bit1) - querys(l - 1, bit1);
e = e * e;
# Function call to calculate E
# in the given range
q = querys(r, bit2) - querys(l - 1, bit2);
sum = (e - q) // 2;
# PrAnswer
print(sum, " ");
# Function to update the Fenwick
# tree and the array element at
# index P to the new value X
def updateArray(a, p, x):
global bit1,bit2
# Function call to update the
# value in 1st Fenwick Tree
update(p, -a[p - 1], bit1);
update(p, x, bit1);
# Function call to update the
# value in 2nd Fenwick Tree
update(p, -a[p - 1] * a[p - 1], bit2);
update(p, x * x, bit2);
a[p - 1] = x;
# Function to solve Q queries
def solveQueries(a, n, Q, query):
# Function Call to build the
# Fenwick Tree
buildFenwickTree(a, n);
for i in range(Q):
# If Query is of type 1
if (query[i][0] == 1):
pairwiseProductSum(a, query[i][1], query[i][2]);
# If Query is of type 2
else:
updateArray(a, query[i][1], query[i][2]);
# Driver Code
if __name__ == '__main__':
A = [5, 7, 2, 3, 1];
N = len(A);
Q = 3;
query = [[1, 1, 3], [2, 2, 5], [1, 2, 5]];
solveQueries(A, N, Q, query);
# This code contributed by shikhasingrajput
59
41
时间复杂度: O(N*log N)用于构建 Fenwick 树
O(log N)用于成对乘积和查询
更新查询的O(log N) 。
辅助空间: O(N)