📜  范围查询中的数组范围查询

📅  最后修改于: 2021-06-27 02:40:34             🧑  作者: Mango

给定大小为n的数组和大小为m的给定命令集。命令从1到m枚举。这些命令可以是以下两种类型的命令:

  1. 类型1 [lr(1 <= l <= r <= n)]:将数组的所有元素加1,其索引属于[l,r]范围。在这些查询中,索引包含在范围内。
  2. 类型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:如上所述,在给定索引为1和2的情况下,我们将简单地将数组索引增加1,因此在执行第一个数组后,我们的数组将变为1 1 0 0 0。
  2. 查询2是类型1:如上所述,我们将简单地将数组索引增加1
    给定的索引是4和5,因此在执行第一个索引之后,我们的数组将变为1 1 0 1 1。
  3. 查询3是类型2:如此类查询的定义中所述,我们将执行范围内所述的查询,即,我们将操作查询而不是数组。给定的范围是1和2,因此我们将再次执行查询1和2,即我们将对类型2查询使用重复方法,因此我们将再次执行查询1,并且数组将是2 2 0 11。现在,当执行查询,我们将执行查询2,结果数组将是2 2 0 2 2。
  4. 查询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. 查询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,因此在执行第一个数组后,我们的数组将变为1。
  2. 查询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现场课程美国》。