给定大小为n的数组和大小为m的给定命令集。命令从1到m枚举。这些命令可以是以下两种类型的命令:
- 类型1 [lr(1 <= l <= r <= n)]:将数组的所有元素加1,其索引属于[l,r]范围。在这些查询中,索引包含在范围内。
- 类型2 [lr(1 <= l <= r <= m)]:执行所有索引在[l,r]范围内的命令。在这些查询中,索引包含在范围内。保证r严格小于当前命令的枚举/数量。
注意:根据问题说明,数组索引从1开始。
例子1
Input : 5 5
1 1 2
1 4 5
2 1 2
2 1 3
2 3 4
Output : 7 7 0 7 7
示例1的说明:
我们的数组最初的大小为5,其每个元素都已初始化为0。
因此,现在的问题是,对于上述示例,我们有5个查询。
- 查询1的类型为1:如上所述,在给定索引为1和2的情况下,我们将简单地将数组索引增加1,因此在执行第一个数组后,我们的数组将变为1 1 0 0 0。
- 查询2是类型1:如上所述,我们将简单地将数组索引增加1
给定的索引是4和5,因此在执行第一个索引之后,我们的数组将变为1 1 0 1 1。 - 查询3是类型2:如此类查询的定义中所述,我们将执行范围内所述的查询,即,我们将操作查询而不是数组。给定的范围是1和2,因此我们将再次执行查询1和2,即我们将对类型2查询使用重复方法,因此我们将再次执行查询1,并且数组将是2 2 0 11。现在,当执行查询,我们将执行查询2,结果数组将是2 2 0 2 2。
- 查询4是类型2:如此类查询的定义中所述,我们将执行范围内所述的查询,即,我们将操作查询而不是数组。给定的范围是1和3,因此我们将再次执行查询1、2和3,即使用重复方法将执行查询1、2和3。再次执行查询1后,数组将为3 3 0 2 2。再次执行查询2后,数组将为3 3 0 3 3。现在由于查询3包含范围,我们将执行查询3,结果数组将为4 4 0 4 4。如上所述。
- 查询5是类型2:最后一个查询将执行上面已说明的第3和第4个查询。执行完第三个查询后,我们的数组将为5 5 0 5 5。在执行第四个查询后,即执行查询1、2和3,我们的数组将是7 7 0 7 7以上是所需结果
例子2
Input : 1 2
1 1 1
1 1 1
Output : 2
示例2的说明:
我们的数组最初的大小为1,其每个元素都已初始化为0。
因此,现在的问题是,对于上面的示例,我们有2个查询。
- 查询1的类型为1:如上所述,在给定索引为1和1的情况下,我们将简单地将数组索引增加1,因此在执行第一个数组后,我们的数组将变为1。
- 查询2的类型为1:如上所述,在给定索引为1和1的情况下,我们将简单地将数组索引增加1,因此在执行第一个数组后,我们的数组将变为2。这给了我们想要的结果
方法1:
此方法是蛮力方法,其中对类型2查询应用简单递归,对于类型1查询执行数组索引中的简单递增。
C++
// CPP program to perform range queries over range
// queries.
#include
using namespace std;
// Function to execute type 1 query
void type1(int arr[], int start, int limit)
{
// incrementing the array by 1 for type
// 1 queries
for (int i = start; i <= limit; i++)
arr[i]++;
}
// Function to execute type 2 query
void type2(int arr[], int query[][3], int start, int limit)
{
for (int i = start; i <= limit; i++) {
// If the query is of type 1 function
// call to type 1 query
if (query[i][0] == 1)
type1(arr, query[i][1], query[i][2]);
// If the query is of type 2 recursive call
// to type 2 query
else if (query[i][0] == 2)
type2(arr, query, query[i][1], query[i][2]);
}
}
// Driver code
int main()
{
// Input size of array amd number of queries
int n = 5, m = 5;
int arr[n + 1];
for (int i = 1; i <= n; i++)
arr[i] = 0;
// Build query matrix
int temp[15] = { 1, 1, 2, 1, 4, 5, 2,
1, 2, 2, 1, 3, 2, 3, 4 };
int query[5][3];
int j = 0;
for (int i = 1; i <= m; i++) {
query[i][0] = temp[j++];
query[i][1] = temp[j++];
query[i][2] = temp[j++];
}
// Perform queries
for (int i = 1; i <= m; i++)
if (query[i][0] == 1)
type1(arr, query[i][1], query[i][2]);
else if (query[i][0] == 2)
type2(arr, query, query[i][1], query[i][2]);
// printing the result
for (int i = 1; i <= n; i++)
cout << arr[i] << " ";
return 0;
}
Java
// Java program to perform range queries
// over range queries.
import java.util.*;
class GFG
{
// Function to execute type 1 query
static void type1(int[] arr, int start, int limit)
{
// incrementing the array by 1 for type
// 1 queries
for (int i = start; i <= limit; i++)
arr[i]++;
}
// Function to execute type 2 query
static void type2(int[] arr, int[][] query,
int start, int limit)
{
for (int i = start; i <= limit; i++)
{
// If the query is of type 1 function
// call to type 1 query
if (query[i][0] == 1)
type1(arr, query[i][1], query[i][2]);
// If the query is of type 2 recursive call
// to type 2 query
else if (query[i][0] == 2)
type2(arr, query, query[i][1],
query[i][2]);
}
}
// Driver Code
public static void main(String[] args)
{
// Input size of array amd number of queries
int n = 5, m = 5;
int[] arr = new int[n + 1];
// Build query matrix
int[] temp = { 1, 1, 2, 1, 4, 5, 2,
1, 2, 2, 1, 3, 2, 3, 4 };
int[][] query = new int[6][4];
int j = 0;
for (int i = 1; i <= m; i++)
{
query[i][0] = temp[j++];
query[i][1] = temp[j++];
query[i][2] = temp[j++];
}
// Perform queries
for (int i = 1; i <= m; i++)
if (query[i][0] == 1)
type1(arr, query[i][1], query[i][2]);
else if (query[i][0] == 2)
type2(arr, query, query[i][1],
query[i][2]);
// printing the result
for (int i = 1; i <= n; i++)
System.out.print(arr[i] + " ");
System.out.println();
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 program to perform range
# queries over range queries.
# Function to execute type 1 query
def type1(arr, start, limit):
# incrementing the array by 1
# for type 1 queries
for i in range(start, limit + 1):
arr[i] += 1
# Function to execute type 2 query
def type2(arr, query, start, limit):
for i in range(start, limit + 1):
# If the query is of type 1
# function call to type 1 query
if (query[i][0] == 1):
type1(arr, query[i][1], query[i][2])
# If the query is of type 2
# recursive call to type 2 query
elif (query[i][0] == 2):
type2(arr, query, query[i][1],
query[i][2])
# Driver code
# Input size of array amd
# number of queries
n = 5
m = 5
arr = [0 for i in range(n + 1)]
# Build query matrix
temp = [1, 1, 2, 1, 4, 5, 2,
1, 2, 2, 1, 3, 2, 3, 4 ]
query = [[0 for i in range(3)]
for j in range(6)]
j = 0
for i in range(1, m + 1):
query[i][0] = temp[j]
j += 1
query[i][1] = temp[j]
j += 1
query[i][2] = temp[j]
j += 1
# Perform queries
for i in range(1, m + 1):
if (query[i][0] == 1):
type1(arr, query[i][1],
query[i][2])
elif (query[i][0] == 2):
type2(arr, query, query[i][1],
query[i][2])
# printing the result
for i in range(1, n + 1):
print(arr[i], end = " ")
# This code is contributed
# by mohit kumar
C#
// C# program to perform range queries
// over range queries.
using System;
class GFG
{
// Function to execute type 1 query
static void type1(int[] arr, int start, int limit)
{
// incrementing the array by 1 for type
// 1 queries
for (int i = start; i <= limit; i++)
arr[i]++;
}
// Function to execute type 2 query
static void type2(int[] arr, int[,] query,
int start, int limit)
{
for (int i = start; i <= limit; i++)
{
// If the query is of type 1 function
// call to type 1 query
if (query[i, 0] == 1)
type1(arr, query[i,1], query[i,2]);
// If the query is of type 2 recursive call
// to type 2 query
else if (query[i, 0] == 2)
type2(arr, query, query[i, 1],
query[i, 2]);
}
}
// Driver Code
public static void Main()
{
// Input size of array amd number of queries
int n = 5, m = 5;
int[] arr = new int[n + 1];
// Build query matrix
int[] temp = { 1, 1, 2, 1, 4, 5, 2,
1, 2, 2, 1, 3, 2, 3, 4 };
int[,] query = new int[6,4];
int j = 0;
for (int i = 1; i <= m; i++)
{
query[i, 0] = temp[j++];
query[i, 1] = temp[j++];
query[i, 2] = temp[j++];
}
// Perform queries
for (int i = 1; i <= m; i++)
if (query[i, 0] == 1)
type1(arr, query[i, 1], query[i, 2]);
else if (query[i, 0] == 2)
type2(arr, query, query[i, 1],
query[i, 2]);
// printing the result
for (int i = 1; i <= n; i++)
Console.Write(arr[i] + " ");
Console.WriteLine();
}
}
// This code is contributed by AbhiThakur
C++
// CPP program to perform range queries over range
// queries.
#include
using namespace std;
// Function to create the record array
void record_sum(int record[], int l, int r,
int n, int adder)
{
for (int i = l; i <= r; i++)
record[i] += adder;
}
// Driver Code
int main()
{
int n = 5, m = 5;
int arr[n];
// Build query matrix
memset(arr, 0, sizeof arr);
int query[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },
{ 2, 1, 2 }, { 2, 1, 3 },
{ 2, 3, 4 } };
int record[m];
memset(record, 0, sizeof record);
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_sum
if (query[i][0] == 2)
record_sum(record, query[i][1] - 1,
query[i][2] - 1, m, record[i] + 1);
// If query is of type 1 then simply add
// 1 to the record array
else
record_sum(record, i, i, m, 1);
}
// for type 1 queries adding the contains of
// record array to the main array record array
for (int i = 0; i < m; i++) {
if (query[i][0] == 1)
record_sum(arr, query[i][1] - 1,
query[i][2] - 1, n, record[i]);
}
// printing the array
for (int i = 0; i < n; i++)
cout << arr[i] << ' ';
return 0;
}
Java
// Java program to perform range queries
// over range queries.
import java.util.Arrays;
class GFG
{
// Function to create the record array
static void record_sum(int record[], int l,
int r, int n, int adder)
{
for (int i = l; i <= r; i++)
{
record[i] += adder;
}
}
// Driver Code
public static void main(String[] args)
{
int n = 5, m = 5;
int arr[] = new int[n];
// Build query matrix
Arrays.fill(arr, 0);
int query[][] = {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
int record[] = new int[m];
Arrays.fill(record, 0);
for (int i = m - 1; i >= 0; i--)
{
// If query is of type 2 then function
// call to record_sum
if (query[i][0] == 2)
{
record_sum(record, query[i][1] - 1,
query[i][2] - 1, m,
record[i] + 1);
}
// If query is of type 1 then
// simply add 1 to the record array
else
{
record_sum(record, i, i, m, 1);
}
}
// for type 1 queries adding the contains of
// record array to the main array record array
for (int i = 0; i < m; i++)
{
if (query[i][0] == 1)
{
record_sum(arr, query[i][1] - 1,
query[i][2] - 1,
n, record[i]);
}
}
// printing the array
for (int i = 0; i < n; i++)
{
System.out.print(arr[i] + " ");
}
}
}
// This code is contributed
// by Princi Singh
Python3
# Python3 program to perform range queries over range
# queries.
# Function to create the record array
def record_sum(record, l, r, n, adder):
for i in range(l, r + 1):
record[i] += adder
# Driver Code
n = 5
m = 5
arr = [0]*n
# Build query matrix
query = [[1, 1, 2 ],[ 1, 4, 5 ],[2, 1, 2 ],
[ 2, 1, 3 ],[ 2, 3, 4]]
record = [0]*m
for i in range(m - 1, -1, -1):
# If query is of type 2 then function
# call to record_sum
if (query[i][0] == 2):
record_sum(record, query[i][1] - 1,
query[i][2] - 1, m, record[i] + 1)
# If query is of type 1 then simply add
# 1 to the record array
else:
record_sum(record, i, i, m, 1)
# for type 1 queries adding the contains of
# record array to the main array record array
for i in range(m):
if (query[i][0] == 1):
record_sum(arr, query[i][1] - 1,
query[i][2] - 1, n, record[i])
# printing the array
for i in range(n):
print(arr[i], end=' ')
# This code is contributed by shubhamsingh10
C#
// C# program to perform range queries
// over range queries.
using System;
class GFG
{
// Function to create the record array
static void record_sum(int []record, int l,
int r, int n, int adder)
{
for (int i = l; i <= r; i++)
{
record[i] += adder;
}
}
// Driver Code
public static void Main(String[] args)
{
int n = 5, m = 5;
int []arr = new int[n];
// Build query matrix
int [,]query = {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
int []record = new int[m];
for (int i = m - 1; i >= 0; i--)
{
// If query is of type 2 then function
// call to record_sum
if (query[i,0] == 2)
{
record_sum(record, query[i,1] - 1,
query[i,2] - 1, m,
record[i] + 1);
}
// If query is of type 1 then
// simply add 1 to the record array
else
{
record_sum(record, i, i, m, 1);
}
}
// for type 1 queries adding the contains of
// record array to the main array record array
for (int i = 0; i < m; i++)
{
if (query[i, 0] == 1)
{
record_sum(arr, query[i, 1] - 1,
query[i, 2] - 1,
n, record[i]);
}
}
// printing the array
for (int i = 0; i < n; i++)
{
Console.Write(arr[i] + " ");
}
}
}
// This code is contributed by Rajput-Ji
C++
// CPP program to perform range queries over range
// queries.
#include
#define max 10000
using namespace std;
// For prefix sum array
void update(int arr[], int l)
{
arr[l] += arr[l - 1];
}
// This function is used to apply square root
// decomposition in the record array
void record_func(int block_size, int block[],
int record[], int l, int r, int value)
{
// traversing first block in range
while (l < r && l % block_size != 0 && l != 0) {
record[l] += value;
l++;
}
// traversing completely overlapped blocks in range
while (l + block_size <= r + 1) {
block[l / block_size] += value;
l += block_size;
}
// traversing last block in range
while (l <= r) {
record[l] += value;
l++;
}
}
// Function to print the resultant array
void print(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
// Driver code
int main()
{
int n = 5, m = 5;
int arr[n], record[m];
int block_size = sqrt(m);
int block[max];
int command[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },
{ 2, 1, 2 }, { 2, 1, 3 },
{ 2, 3, 4 } };
memset(arr, 0, sizeof arr);
memset(record, 0, sizeof record);
memset(block, 0, sizeof block);
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_func
if (command[i][0] == 2) {
int x = i / (block_size);
record_func(block_size, block, record,
command[i][1] - 1, command[i][2] - 1,
(block[x] + record[i] + 1));
}
// If query is of type 1 then simply add
// 1 to the record array
else
record[i]++;
}
// Merging the value of the block in the record array
for (int i = 0; i < m; i++) {
int check = (i / block_size);
record[i] += block[check];
}
for (int i = 0; i < m; i++) {
// If query is of type 1 then the array
// elements are over-written by the record
// array
if (command[i][0] == 1) {
arr[command[i][1] - 1] += record[i];
if ((command[i][2] - 1) < n - 1)
arr[(command[i][2])] -= record[i];
}
}
// The prefix sum of the array
for (int i = 1; i < n; i++)
update(arr, i);
// Printing the resultant array
print(arr, n);
return 0;
}
Java
// Java program to perform range queries over range
// queries.
public class GFG {
static final int max = 10000;
// For prefix sum array
static void update(int arr[], int l) {
arr[l] += arr[l - 1];
}
// This function is used to apply square root
// decomposition in the record array
static void record_func(int block_size, int block[],
int record[], int l, int r, int value) {
// traversing first block in range
while (l < r && l % block_size != 0 && l != 0) {
record[l] += value;
l++;
}
// traversing completely overlapped blocks in range
while (l + block_size <= r + 1) {
block[l / block_size] += value;
l += block_size;
}
// traversing last block in range
while (l <= r) {
record[l] += value;
l++;
}
}
// Function to print the resultant array
static void print(int arr[], int n) {
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
}
// Driver code
public static void main(String[] args) {
int n = 5, m = 5;
int arr[] = new int[n], record[] = new int[m];
int block_size = (int) Math.sqrt(m);
int block[] = new int[max];
int command[][] = {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_func
if (command[i][0] == 2) {
int x = i / (block_size);
record_func(block_size, block, record,
command[i][1] - 1, command[i][2] - 1,
(block[x] + record[i] + 1));
} // If query is of type 1 then simply add
// 1 to the record array
else {
record[i]++;
}
}
// Merging the value of the block in the record array
for (int i = 0; i < m; i++) {
int check = (i / block_size);
record[i] += block[check];
}
for (int i = 0; i < m; i++) {
// If query is of type 1 then the array
// elements are over-written by the record
// array
if (command[i][0] == 1) {
arr[command[i][1] - 1] += record[i];
if ((command[i][2] - 1) < n - 1) {
arr[(command[i][2])] -= record[i];
}
}
}
// The prefix sum of the array
for (int i = 1; i < n; i++) {
update(arr, i);
}
// Printing the resultant array
print(arr, n);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to perform range
# queries over range queries.
import math
max = 10000
# For prefix sum array
def update(arr, l):
arr[l] += arr[l - 1]
# This function is used to apply square root
# decomposition in the record array
def record_func(block_size, block,
record, l, r, value):
# Traversing first block in range
while (l < r and
l % block_size != 0 and
l != 0):
record[l] += value
l += 1
# Traversing completely overlapped
# blocks in range
while (l + block_size <= r + 1):
block[l // block_size] += value
l += block_size
# Traversing last block in range
while (l <= r):
record[l] += value
l += 1
# Function to print the resultant array
def print_array(arr, n):
for i in range(n):
print(arr[i], end = " ")
# Driver code
if __name__ == "__main__":
n = 5
m = 5
arr = [0] * n
record = [0] * m
block_size = (int)(math.sqrt(m))
block = [0] * max
command = [ [ 1, 1, 2 ],
[ 1, 4, 5 ],
[ 2, 1, 2 ],
[ 2, 1, 3 ],
[ 2, 3, 4 ] ]
for i in range(m - 1, -1, -1):
# If query is of type 2 then function
# call to record_func
if (command[i][0] == 2):
x = i // (block_size)
record_func(block_size, block,
record, command[i][1] - 1,
command[i][2] - 1,
(block[x] + record[i] + 1))
# If query is of type 1 then simply add
# 1 to the record array
else:
record[i] += 1
# Merging the value of the block
# in the record array
for i in range(m):
check = (i // block_size)
record[i] += block[check]
for i in range(m):
# If query is of type 1 then the array
# elements are over-written by the record
# array
if (command[i][0] == 1):
arr[command[i][1] - 1] += record[i]
if ((command[i][2] - 1) < n - 1):
arr[(command[i][2])] -= record[i]
# The prefix sum of the array
for i in range(1, n):
update(arr, i)
# Printing the resultant array
print_array(arr, n)
# This code is contributed by chitranayal
C#
// C# program to perform range queries over range
// queries.
using System;
public class GFG {
static readonly int max = 10000;
// For prefix sum array
static void update(int []arr, int l) {
arr[l] += arr[l - 1];
}
// This function is used to apply square root
// decomposition in the record array
static void record_func(int block_size, int []block,
int []record, int l, int r, int value) {
// traversing first block in range
while (l < r && l % block_size != 0 && l != 0) {
record[l] += value;
l++;
}
// traversing completely overlapped blocks in range
while (l + block_size <= r + 1) {
block[l / block_size] += value;
l += block_size;
}
// traversing last block in range
while (l <= r) {
record[l] += value;
l++;
}
}
// Function to print the resultant array
static void print(int []arr, int n) {
for (int i = 0; i < n; i++) {
Console.Write(arr[i] + " ");
}
}
// Driver code
public static void Main() {
int n = 5, m = 5;
int []arr = new int[n]; int []record = new int[m];
int block_size = (int) Math.Sqrt(m);
int []block = new int[max];
int [,]command= {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_func
if (command[i,0] == 2) {
int x = i / (block_size);
record_func(block_size, block, record,
command[i,1] - 1, command[i,2] - 1,
(block[x] + record[i] + 1));
} // If query is of type 1 then simply add
// 1 to the record array
else {
record[i]++;
}
}
// Merging the value of the block in the record array
for (int i = 0; i < m; i++) {
int check = (i / block_size);
record[i] += block[check];
}
for (int i = 0; i < m; i++) {
// If query is of type 1 then the array
// elements are over-written by the record
// array
if (command[i,0] == 1) {
arr[command[i,1] - 1] += record[i];
if ((command[i,2] - 1) < n - 1) {
arr[(command[i,2])] -= record[i];
}
}
}
// The prefix sum of the array
for (int i = 1; i < n; i++) {
update(arr, i);
}
// Printing the resultant array
print(arr, n);
}
}
// This code is contributed by 29AjayKumar
C++
// C++ program to perform range queries over range
// queries.
#include
using namespace std;
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n) {
// Add 'val' to current node of BI Tree
BITree[index] = (val + BITree[index]);
// Update index to that of parent in update View
index = (index + (index & (-index)));
}
return;
}
// Constructs and returns a Binary Indexed Tree for given
// array of size n.
int* constructBITree(int n)
{
// Create and initialize BITree[] as 0
int* BITree = new int[n + 1];
for (int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[]
int getSum(int BITree[], int index)
{
int sum = 0;
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index > 0) {
// Add element of BITree to sum
sum = (sum + BITree[index]);
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Function to update the BITree
void update(int BITree[], int l, int r, int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
return;
}
// Driver code
int main()
{
int n = 5, m = 5;
int temp[15] = { 1, 1, 2, 1, 4, 5, 2, 1, 2,
2, 1, 3, 2, 3, 4 };
int q[5][3];
int j = 0;
for (int i = 1; i <= m; i++) {
q[i][0] = temp[j++];
q[i][1] = temp[j++];
q[i][2] = temp[j++];
}
// BITree for query of type 2
int* BITree = constructBITree(m);
// BITree for query of type 1
int* BITree2 = constructBITree(n);
// Input the queries in a 2D matrix
for (int i = 1; i <= m; i++)
cin >> q[i][0] >> q[i][1] >> q[i][2];
// If query is of type 2 then function call
// to update with BITree
for (int i = m; i >= 1; i--)
if (q[i][0] == 2)
update(BITree, q[i][1] - 1, q[i][2] - 1, m, 1);
for (int i = m; i >= 1; i--) {
if (q[i][0] == 2) {
long int val = getSum(BITree, i - 1);
update(BITree, q[i][1] - 1, q[i][2] - 1, m, val);
}
}
// If query is of type 1 then function call
// to update with BITree2
for (int i = m; i >= 1; i--) {
if (q[i][0] == 1) {
long int val = getSum(BITree, i - 1);
update(BITree2, q[i][1] - 1, q[i][2] - 1,
n, (val + 1));
}
}
for (int i = 1; i <= n; i++)
cout << (getSum(BITree2, i - 1)) << " ";
return 0;
}
Java
// Java program to perform range queries over range
// queries.
import java.io.*;
import java.util.*;
class GFG
{
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
static void updateBIT(int BITree[], int n, int index, int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] = (val + BITree[index]);
// Update index to that of parent in update View
index = (index + (index & (-index)));
}
return;
}
// Constructs and returns a Binary Indexed Tree for given
// array of size n.
static int[] constructBITree(int n)
{
// Create and initialize BITree[] as 0
int[] BITree = new int[n + 1];
for (int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[]
static int getSum(int BITree[], int index)
{
int sum = 0;
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index > 0)
{
// Add element of BITree to sum
sum = (sum + BITree[index]);
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Function to update the BITree
static void update(int BITree[], int l, int r, int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
return;
}
// Driver code
public static void main (String[] args)
{
int n = 5, m = 5;
int temp[] = { 1, 1, 2, 1, 4, 5, 2, 1, 2,
2, 1, 3, 2, 3, 4 };
int[][] q = new int[6][3];
int j = 0;
for (int i = 1; i <= m; i++) {
q[i][0] = temp[j++];
q[i][1] = temp[j++];
q[i][2] = temp[j++];
}
// BITree for query of type 2
int[] BITree = constructBITree(m);
// BITree for query of type 1
int[] BITree2 = constructBITree(n);
// Input the queries in a 2D matrix
/*Scanner sc=new Scanner(System.in);
for (int i = 1; i <= m; i++)
{
q[i][0]=sc.nextInt();
q[i][1]=sc.nextInt();
q[i][2]=sc.nextInt();
}*/
// If query is of type 2 then function call
// to update with BITree
for (int i = m; i >= 1; i--)
if (q[i][0] == 2)
update(BITree, q[i][1] - 1, q[i][2] - 1, m, 1);
for (int i = m; i >= 1; i--) {
if (q[i][0] == 2) {
int val = getSum(BITree, i - 1);
update(BITree, q[i][1] - 1, q[i][2] - 1, m, val);
}
}
// If query is of type 1 then function call
// to update with BITree2
for (int i = m; i >= 1; i--) {
if (q[i][0] == 1) {
int val = getSum(BITree, i - 1);
update(BITree2, q[i][1] - 1, q[i][2] - 1,
n, (val + 1));
}
}
for (int i = 1; i <= n; i++)
System.out.print(getSum(BITree2, i - 1)+" ");
}
}
// This code is contributed by avanitrachhadiya2155
C#
// C# program to perform range queries over range
// queries.
using System;
class GFG{
// Updates a node in Binary Index Tree (BITree)
// at given index in BITree. The given value
// 'val' is added to BITree[i] and
// all of its ancestors in tree.
static void updateBIT(int[] BITree, int n,
int index, int val)
{
// index in BITree[] is 1 more than
// the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] = (val + BITree[index]);
// Update index to that of parent in update View
index = (index + (index & (-index)));
}
return;
}
// Constructs and returns a Binary Indexed
// Tree for given array of size n.
static int[] constructBITree(int n)
{
// Create and initialize BITree[] as 0
int[] BITree = new int[n + 1];
for(int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[]
static int getSum(int[] BITree, int index)
{
int sum = 0;
// index in BITree[] is 1 more than
// the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index > 0)
{
// Add element of BITree to sum
sum = (sum + BITree[index]);
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Function to update the BITree
static void update(int[] BITree, int l, int r,
int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
return;
}
// Driver code
static public void Main()
{
int n = 5, m = 5;
int[] temp = { 1, 1, 2, 1, 4, 5, 2,
1, 2, 2, 1, 3, 2, 3, 4 };
int[,] q = new int[6, 3];
int j = 0;
for(int i = 1; i <= m; i++)
{
q[i, 0] = temp[j++];
q[i, 1] = temp[j++];
q[i, 2] = temp[j++];
}
// BITree for query of type 2
int[] BITree = constructBITree(m);
// BITree for query of type 1
int[] BITree2 = constructBITree(n);
// If query is of type 2 then function call
// to update with BITree
for(int i = m; i >= 1; i--)
if (q[i, 0] == 2)
update(BITree, q[i, 1] - 1,
q[i, 2] - 1, m, 1);
for(int i = m; i >= 1; i--)
{
if (q[i,0] == 2)
{
int val = getSum(BITree, i - 1);
update(BITree, q[i, 1] - 1,
q[i, 2] - 1, m, val);
}
}
// If query is of type 1 then function call
// to update with BITree2
for(int i = m; i >= 1; i--)
{
if (q[i,0] == 1)
{
int val = getSum(BITree, i - 1);
update(BITree2, q[i, 1] - 1, q[i, 2] - 1,
n, (val + 1));
}
}
for(int i = 1; i <= n; i++)
Console.Write(getSum(BITree2, i - 1) + " ");
}
}
// This code is contributed by rag2127
输出:
7 7 0 7 7
上面代码的时间复杂度是O(2 ^ m)
方法2:
在此方法中,我们使用一个额外的数组来创建记录数组,以查找执行特定查询的时间,并且在创建记录数组后,我们只需执行类型为1的查询,并将记录数组的包含内容简单地添加到主数组,这将给我们结果数组。
C++
// CPP program to perform range queries over range
// queries.
#include
using namespace std;
// Function to create the record array
void record_sum(int record[], int l, int r,
int n, int adder)
{
for (int i = l; i <= r; i++)
record[i] += adder;
}
// Driver Code
int main()
{
int n = 5, m = 5;
int arr[n];
// Build query matrix
memset(arr, 0, sizeof arr);
int query[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },
{ 2, 1, 2 }, { 2, 1, 3 },
{ 2, 3, 4 } };
int record[m];
memset(record, 0, sizeof record);
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_sum
if (query[i][0] == 2)
record_sum(record, query[i][1] - 1,
query[i][2] - 1, m, record[i] + 1);
// If query is of type 1 then simply add
// 1 to the record array
else
record_sum(record, i, i, m, 1);
}
// for type 1 queries adding the contains of
// record array to the main array record array
for (int i = 0; i < m; i++) {
if (query[i][0] == 1)
record_sum(arr, query[i][1] - 1,
query[i][2] - 1, n, record[i]);
}
// printing the array
for (int i = 0; i < n; i++)
cout << arr[i] << ' ';
return 0;
}
Java
// Java program to perform range queries
// over range queries.
import java.util.Arrays;
class GFG
{
// Function to create the record array
static void record_sum(int record[], int l,
int r, int n, int adder)
{
for (int i = l; i <= r; i++)
{
record[i] += adder;
}
}
// Driver Code
public static void main(String[] args)
{
int n = 5, m = 5;
int arr[] = new int[n];
// Build query matrix
Arrays.fill(arr, 0);
int query[][] = {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
int record[] = new int[m];
Arrays.fill(record, 0);
for (int i = m - 1; i >= 0; i--)
{
// If query is of type 2 then function
// call to record_sum
if (query[i][0] == 2)
{
record_sum(record, query[i][1] - 1,
query[i][2] - 1, m,
record[i] + 1);
}
// If query is of type 1 then
// simply add 1 to the record array
else
{
record_sum(record, i, i, m, 1);
}
}
// for type 1 queries adding the contains of
// record array to the main array record array
for (int i = 0; i < m; i++)
{
if (query[i][0] == 1)
{
record_sum(arr, query[i][1] - 1,
query[i][2] - 1,
n, record[i]);
}
}
// printing the array
for (int i = 0; i < n; i++)
{
System.out.print(arr[i] + " ");
}
}
}
// This code is contributed
// by Princi Singh
Python3
# Python3 program to perform range queries over range
# queries.
# Function to create the record array
def record_sum(record, l, r, n, adder):
for i in range(l, r + 1):
record[i] += adder
# Driver Code
n = 5
m = 5
arr = [0]*n
# Build query matrix
query = [[1, 1, 2 ],[ 1, 4, 5 ],[2, 1, 2 ],
[ 2, 1, 3 ],[ 2, 3, 4]]
record = [0]*m
for i in range(m - 1, -1, -1):
# If query is of type 2 then function
# call to record_sum
if (query[i][0] == 2):
record_sum(record, query[i][1] - 1,
query[i][2] - 1, m, record[i] + 1)
# If query is of type 1 then simply add
# 1 to the record array
else:
record_sum(record, i, i, m, 1)
# for type 1 queries adding the contains of
# record array to the main array record array
for i in range(m):
if (query[i][0] == 1):
record_sum(arr, query[i][1] - 1,
query[i][2] - 1, n, record[i])
# printing the array
for i in range(n):
print(arr[i], end=' ')
# This code is contributed by shubhamsingh10
C#
// C# program to perform range queries
// over range queries.
using System;
class GFG
{
// Function to create the record array
static void record_sum(int []record, int l,
int r, int n, int adder)
{
for (int i = l; i <= r; i++)
{
record[i] += adder;
}
}
// Driver Code
public static void Main(String[] args)
{
int n = 5, m = 5;
int []arr = new int[n];
// Build query matrix
int [,]query = {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
int []record = new int[m];
for (int i = m - 1; i >= 0; i--)
{
// If query is of type 2 then function
// call to record_sum
if (query[i,0] == 2)
{
record_sum(record, query[i,1] - 1,
query[i,2] - 1, m,
record[i] + 1);
}
// If query is of type 1 then
// simply add 1 to the record array
else
{
record_sum(record, i, i, m, 1);
}
}
// for type 1 queries adding the contains of
// record array to the main array record array
for (int i = 0; i < m; i++)
{
if (query[i, 0] == 1)
{
record_sum(arr, query[i, 1] - 1,
query[i, 2] - 1,
n, record[i]);
}
}
// printing the array
for (int i = 0; i < n; i++)
{
Console.Write(arr[i] + " ");
}
}
}
// This code is contributed by Rajput-Ji
输出 :
7 7 0 7 7
上面代码的时间复杂度是O(n ^ 2)
方法3:
通过对记录数组应用平方根分解,使此方法更加有效。
C++
// CPP program to perform range queries over range
// queries.
#include
#define max 10000
using namespace std;
// For prefix sum array
void update(int arr[], int l)
{
arr[l] += arr[l - 1];
}
// This function is used to apply square root
// decomposition in the record array
void record_func(int block_size, int block[],
int record[], int l, int r, int value)
{
// traversing first block in range
while (l < r && l % block_size != 0 && l != 0) {
record[l] += value;
l++;
}
// traversing completely overlapped blocks in range
while (l + block_size <= r + 1) {
block[l / block_size] += value;
l += block_size;
}
// traversing last block in range
while (l <= r) {
record[l] += value;
l++;
}
}
// Function to print the resultant array
void print(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
// Driver code
int main()
{
int n = 5, m = 5;
int arr[n], record[m];
int block_size = sqrt(m);
int block[max];
int command[5][3] = { { 1, 1, 2 }, { 1, 4, 5 },
{ 2, 1, 2 }, { 2, 1, 3 },
{ 2, 3, 4 } };
memset(arr, 0, sizeof arr);
memset(record, 0, sizeof record);
memset(block, 0, sizeof block);
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_func
if (command[i][0] == 2) {
int x = i / (block_size);
record_func(block_size, block, record,
command[i][1] - 1, command[i][2] - 1,
(block[x] + record[i] + 1));
}
// If query is of type 1 then simply add
// 1 to the record array
else
record[i]++;
}
// Merging the value of the block in the record array
for (int i = 0; i < m; i++) {
int check = (i / block_size);
record[i] += block[check];
}
for (int i = 0; i < m; i++) {
// If query is of type 1 then the array
// elements are over-written by the record
// array
if (command[i][0] == 1) {
arr[command[i][1] - 1] += record[i];
if ((command[i][2] - 1) < n - 1)
arr[(command[i][2])] -= record[i];
}
}
// The prefix sum of the array
for (int i = 1; i < n; i++)
update(arr, i);
// Printing the resultant array
print(arr, n);
return 0;
}
Java
// Java program to perform range queries over range
// queries.
public class GFG {
static final int max = 10000;
// For prefix sum array
static void update(int arr[], int l) {
arr[l] += arr[l - 1];
}
// This function is used to apply square root
// decomposition in the record array
static void record_func(int block_size, int block[],
int record[], int l, int r, int value) {
// traversing first block in range
while (l < r && l % block_size != 0 && l != 0) {
record[l] += value;
l++;
}
// traversing completely overlapped blocks in range
while (l + block_size <= r + 1) {
block[l / block_size] += value;
l += block_size;
}
// traversing last block in range
while (l <= r) {
record[l] += value;
l++;
}
}
// Function to print the resultant array
static void print(int arr[], int n) {
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
}
// Driver code
public static void main(String[] args) {
int n = 5, m = 5;
int arr[] = new int[n], record[] = new int[m];
int block_size = (int) Math.sqrt(m);
int block[] = new int[max];
int command[][] = {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_func
if (command[i][0] == 2) {
int x = i / (block_size);
record_func(block_size, block, record,
command[i][1] - 1, command[i][2] - 1,
(block[x] + record[i] + 1));
} // If query is of type 1 then simply add
// 1 to the record array
else {
record[i]++;
}
}
// Merging the value of the block in the record array
for (int i = 0; i < m; i++) {
int check = (i / block_size);
record[i] += block[check];
}
for (int i = 0; i < m; i++) {
// If query is of type 1 then the array
// elements are over-written by the record
// array
if (command[i][0] == 1) {
arr[command[i][1] - 1] += record[i];
if ((command[i][2] - 1) < n - 1) {
arr[(command[i][2])] -= record[i];
}
}
}
// The prefix sum of the array
for (int i = 1; i < n; i++) {
update(arr, i);
}
// Printing the resultant array
print(arr, n);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to perform range
# queries over range queries.
import math
max = 10000
# For prefix sum array
def update(arr, l):
arr[l] += arr[l - 1]
# This function is used to apply square root
# decomposition in the record array
def record_func(block_size, block,
record, l, r, value):
# Traversing first block in range
while (l < r and
l % block_size != 0 and
l != 0):
record[l] += value
l += 1
# Traversing completely overlapped
# blocks in range
while (l + block_size <= r + 1):
block[l // block_size] += value
l += block_size
# Traversing last block in range
while (l <= r):
record[l] += value
l += 1
# Function to print the resultant array
def print_array(arr, n):
for i in range(n):
print(arr[i], end = " ")
# Driver code
if __name__ == "__main__":
n = 5
m = 5
arr = [0] * n
record = [0] * m
block_size = (int)(math.sqrt(m))
block = [0] * max
command = [ [ 1, 1, 2 ],
[ 1, 4, 5 ],
[ 2, 1, 2 ],
[ 2, 1, 3 ],
[ 2, 3, 4 ] ]
for i in range(m - 1, -1, -1):
# If query is of type 2 then function
# call to record_func
if (command[i][0] == 2):
x = i // (block_size)
record_func(block_size, block,
record, command[i][1] - 1,
command[i][2] - 1,
(block[x] + record[i] + 1))
# If query is of type 1 then simply add
# 1 to the record array
else:
record[i] += 1
# Merging the value of the block
# in the record array
for i in range(m):
check = (i // block_size)
record[i] += block[check]
for i in range(m):
# If query is of type 1 then the array
# elements are over-written by the record
# array
if (command[i][0] == 1):
arr[command[i][1] - 1] += record[i]
if ((command[i][2] - 1) < n - 1):
arr[(command[i][2])] -= record[i]
# The prefix sum of the array
for i in range(1, n):
update(arr, i)
# Printing the resultant array
print_array(arr, n)
# This code is contributed by chitranayal
C#
// C# program to perform range queries over range
// queries.
using System;
public class GFG {
static readonly int max = 10000;
// For prefix sum array
static void update(int []arr, int l) {
arr[l] += arr[l - 1];
}
// This function is used to apply square root
// decomposition in the record array
static void record_func(int block_size, int []block,
int []record, int l, int r, int value) {
// traversing first block in range
while (l < r && l % block_size != 0 && l != 0) {
record[l] += value;
l++;
}
// traversing completely overlapped blocks in range
while (l + block_size <= r + 1) {
block[l / block_size] += value;
l += block_size;
}
// traversing last block in range
while (l <= r) {
record[l] += value;
l++;
}
}
// Function to print the resultant array
static void print(int []arr, int n) {
for (int i = 0; i < n; i++) {
Console.Write(arr[i] + " ");
}
}
// Driver code
public static void Main() {
int n = 5, m = 5;
int []arr = new int[n]; int []record = new int[m];
int block_size = (int) Math.Sqrt(m);
int []block = new int[max];
int [,]command= {{1, 1, 2}, {1, 4, 5},
{2, 1, 2}, {2, 1, 3},
{2, 3, 4}};
for (int i = m - 1; i >= 0; i--) {
// If query is of type 2 then function
// call to record_func
if (command[i,0] == 2) {
int x = i / (block_size);
record_func(block_size, block, record,
command[i,1] - 1, command[i,2] - 1,
(block[x] + record[i] + 1));
} // If query is of type 1 then simply add
// 1 to the record array
else {
record[i]++;
}
}
// Merging the value of the block in the record array
for (int i = 0; i < m; i++) {
int check = (i / block_size);
record[i] += block[check];
}
for (int i = 0; i < m; i++) {
// If query is of type 1 then the array
// elements are over-written by the record
// array
if (command[i,0] == 1) {
arr[command[i,1] - 1] += record[i];
if ((command[i,2] - 1) < n - 1) {
arr[(command[i,2])] -= record[i];
}
}
}
// The prefix sum of the array
for (int i = 1; i < n; i++) {
update(arr, i);
}
// Printing the resultant array
print(arr, n);
}
}
// This code is contributed by 29AjayKumar
输出 :
7 7 0 7 7
方法4:
通过分别为查询1和查询2创建两个二进制索引树来应用二进制索引树或Fenwick树,使该方法更加有效。
C++
// C++ program to perform range queries over range
// queries.
#include
using namespace std;
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int BITree[], int n, int index, int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n) {
// Add 'val' to current node of BI Tree
BITree[index] = (val + BITree[index]);
// Update index to that of parent in update View
index = (index + (index & (-index)));
}
return;
}
// Constructs and returns a Binary Indexed Tree for given
// array of size n.
int* constructBITree(int n)
{
// Create and initialize BITree[] as 0
int* BITree = new int[n + 1];
for (int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[]
int getSum(int BITree[], int index)
{
int sum = 0;
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index > 0) {
// Add element of BITree to sum
sum = (sum + BITree[index]);
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Function to update the BITree
void update(int BITree[], int l, int r, int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
return;
}
// Driver code
int main()
{
int n = 5, m = 5;
int temp[15] = { 1, 1, 2, 1, 4, 5, 2, 1, 2,
2, 1, 3, 2, 3, 4 };
int q[5][3];
int j = 0;
for (int i = 1; i <= m; i++) {
q[i][0] = temp[j++];
q[i][1] = temp[j++];
q[i][2] = temp[j++];
}
// BITree for query of type 2
int* BITree = constructBITree(m);
// BITree for query of type 1
int* BITree2 = constructBITree(n);
// Input the queries in a 2D matrix
for (int i = 1; i <= m; i++)
cin >> q[i][0] >> q[i][1] >> q[i][2];
// If query is of type 2 then function call
// to update with BITree
for (int i = m; i >= 1; i--)
if (q[i][0] == 2)
update(BITree, q[i][1] - 1, q[i][2] - 1, m, 1);
for (int i = m; i >= 1; i--) {
if (q[i][0] == 2) {
long int val = getSum(BITree, i - 1);
update(BITree, q[i][1] - 1, q[i][2] - 1, m, val);
}
}
// If query is of type 1 then function call
// to update with BITree2
for (int i = m; i >= 1; i--) {
if (q[i][0] == 1) {
long int val = getSum(BITree, i - 1);
update(BITree2, q[i][1] - 1, q[i][2] - 1,
n, (val + 1));
}
}
for (int i = 1; i <= n; i++)
cout << (getSum(BITree2, i - 1)) << " ";
return 0;
}
Java
// Java program to perform range queries over range
// queries.
import java.io.*;
import java.util.*;
class GFG
{
// Updates a node in Binary Index Tree (BITree) at given index
// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
static void updateBIT(int BITree[], int n, int index, int val)
{
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] = (val + BITree[index]);
// Update index to that of parent in update View
index = (index + (index & (-index)));
}
return;
}
// Constructs and returns a Binary Indexed Tree for given
// array of size n.
static int[] constructBITree(int n)
{
// Create and initialize BITree[] as 0
int[] BITree = new int[n + 1];
for (int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[]
static int getSum(int BITree[], int index)
{
int sum = 0;
// index in BITree[] is 1 more than the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index > 0)
{
// Add element of BITree to sum
sum = (sum + BITree[index]);
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Function to update the BITree
static void update(int BITree[], int l, int r, int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
return;
}
// Driver code
public static void main (String[] args)
{
int n = 5, m = 5;
int temp[] = { 1, 1, 2, 1, 4, 5, 2, 1, 2,
2, 1, 3, 2, 3, 4 };
int[][] q = new int[6][3];
int j = 0;
for (int i = 1; i <= m; i++) {
q[i][0] = temp[j++];
q[i][1] = temp[j++];
q[i][2] = temp[j++];
}
// BITree for query of type 2
int[] BITree = constructBITree(m);
// BITree for query of type 1
int[] BITree2 = constructBITree(n);
// Input the queries in a 2D matrix
/*Scanner sc=new Scanner(System.in);
for (int i = 1; i <= m; i++)
{
q[i][0]=sc.nextInt();
q[i][1]=sc.nextInt();
q[i][2]=sc.nextInt();
}*/
// If query is of type 2 then function call
// to update with BITree
for (int i = m; i >= 1; i--)
if (q[i][0] == 2)
update(BITree, q[i][1] - 1, q[i][2] - 1, m, 1);
for (int i = m; i >= 1; i--) {
if (q[i][0] == 2) {
int val = getSum(BITree, i - 1);
update(BITree, q[i][1] - 1, q[i][2] - 1, m, val);
}
}
// If query is of type 1 then function call
// to update with BITree2
for (int i = m; i >= 1; i--) {
if (q[i][0] == 1) {
int val = getSum(BITree, i - 1);
update(BITree2, q[i][1] - 1, q[i][2] - 1,
n, (val + 1));
}
}
for (int i = 1; i <= n; i++)
System.out.print(getSum(BITree2, i - 1)+" ");
}
}
// This code is contributed by avanitrachhadiya2155
C#
// C# program to perform range queries over range
// queries.
using System;
class GFG{
// Updates a node in Binary Index Tree (BITree)
// at given index in BITree. The given value
// 'val' is added to BITree[i] and
// all of its ancestors in tree.
static void updateBIT(int[] BITree, int n,
int index, int val)
{
// index in BITree[] is 1 more than
// the index in arr[]
index = index + 1;
// Traverse all ancestors and add 'val'
while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] = (val + BITree[index]);
// Update index to that of parent in update View
index = (index + (index & (-index)));
}
return;
}
// Constructs and returns a Binary Indexed
// Tree for given array of size n.
static int[] constructBITree(int n)
{
// Create and initialize BITree[] as 0
int[] BITree = new int[n + 1];
for(int i = 1; i <= n; i++)
BITree[i] = 0;
return BITree;
}
// Returns sum of arr[0..index]. This function assumes
// that the array is preprocessed and partial sums of
// array elements are stored in BITree[]
static int getSum(int[] BITree, int index)
{
int sum = 0;
// index in BITree[] is 1 more than
// the index in arr[]
index = index + 1;
// Traverse ancestors of BITree[index]
while (index > 0)
{
// Add element of BITree to sum
sum = (sum + BITree[index]);
// Move index to parent node in getSum View
index -= index & (-index);
}
return sum;
}
// Function to update the BITree
static void update(int[] BITree, int l, int r,
int n, int val)
{
updateBIT(BITree, n, l, val);
updateBIT(BITree, n, r + 1, -val);
return;
}
// Driver code
static public void Main()
{
int n = 5, m = 5;
int[] temp = { 1, 1, 2, 1, 4, 5, 2,
1, 2, 2, 1, 3, 2, 3, 4 };
int[,] q = new int[6, 3];
int j = 0;
for(int i = 1; i <= m; i++)
{
q[i, 0] = temp[j++];
q[i, 1] = temp[j++];
q[i, 2] = temp[j++];
}
// BITree for query of type 2
int[] BITree = constructBITree(m);
// BITree for query of type 1
int[] BITree2 = constructBITree(n);
// If query is of type 2 then function call
// to update with BITree
for(int i = m; i >= 1; i--)
if (q[i, 0] == 2)
update(BITree, q[i, 1] - 1,
q[i, 2] - 1, m, 1);
for(int i = m; i >= 1; i--)
{
if (q[i,0] == 2)
{
int val = getSum(BITree, i - 1);
update(BITree, q[i, 1] - 1,
q[i, 2] - 1, m, val);
}
}
// If query is of type 1 then function call
// to update with BITree2
for(int i = m; i >= 1; i--)
{
if (q[i,0] == 1)
{
int val = getSum(BITree, i - 1);
update(BITree2, q[i, 1] - 1, q[i, 2] - 1,
n, (val + 1));
}
}
for(int i = 1; i <= n; i++)
Console.Write(getSum(BITree2, i - 1) + " ");
}
}
// This code is contributed by rag2127
输出 :
7 7 0 7 7
方法3和方法4的时间复杂度为O(log n) 。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。