
- C++ Basics
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Data Types
- C++ Variable Types
- C++ Variable Scope
- C++ Constants/Literals
- C++ Modifier Types
- C++ Storage Classes
- C++ Operators
- C++ Loop Types
- C++ Decision Making
- C++ Functions
- C++ Numbers
- C++ Arrays
- C++ Strings
- C++ Pointers
- C++ References
- C++ Date & Time
- C++ Basic Input/Output
- C++ Data Structures
- C++ Object Oriented
- C++ Classes & Objects
- C++ Inheritance
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
C++ Range Sum Queries and Update with Square Root
Given an array and several queries. Also, there are two types of query, i.e., update[ L, R ] means update elements from L to R with their square roots, and query[ L, R ] means to calculate the sum of elements from L to R.We are assuming a 1-based indexed array, for example
Input: nums[ ] = { 0, 9, 4, 1, 5, 2, 3 }, Query[ ] = { {1, 1, 3}, {2, 1, 2}, {1, 2, 5}, { 1, 4, 5}} Output: 14 10 7 1st element of 1st query is 1 means we need to calculate range sum from 1 to 3 i.e 9 + 4 + 1 = 14 1st element of 2nd query is 2 means we need to update range element from 1 to 2 with their square roots now new arr[] array is { 3, 2, 1, 5, 2, 3 } 1st element of 3rd query is 1 means we need to calculate range sum from 2 to 5 i.e 2 + 1 + 5 + 2 = 10 1st element of the 4th query is 1 means we need to calculate the range sum from 4 to 5 i.e 5 + 2 = 7 Input: nums[] = { 0, 3, 2, 4, 16, 2 }, Query[ ] = {{1, 1, 3}, {2, 2, 5}} Output: 9
Approach to Find the Solution
Simple Approach
We can use a loop till queries end and return the sum of range for sum query and update the array for the update query. But time complexity of this program will be O(q * n). Let’s look for an efficient approach.
Efficient Approach
Program could be efficient if we decrease the number of operations or number of iterations. We can use Binary Indexed Trees, in which we create an array and use two functions for update and sum query. For the update query, if the element is 1, there is no need to update it as its square root will be one only. Now we can use a set to store the index of greater than one and use binary search for finding Lth index and increment it till every range element is updated. Then check if the updated value becomes one, then remove that index from the set because it will always be 1 for any update queries.
For the sum query, we can do query(R) - query(L-1).
Example
C++ Code for the Above Approach
#include <bits/stdc++.h> using namespace std; // Maximum size input array can be const int m = 200; // Creating Binary Indexed tree. int binary_indexed[m + 1]; // for update query void update_q(int a, int x, int n){ while(a <= n) { binary_indexed[a] += x; a += a & -a; } } // Function to calculate sum range. int sum_q(int a){ int s = 0; while(a > 0) { s += binary_indexed[a]; a -= a & -a; } return s; } int main(){ int no_query = 4; int nums[] = { 0, 9, 4, 1, 5, 2, 3 }; int n = sizeof(nums) / sizeof(nums[0]); // 2-D array for queries. int q[no_query + 1][3]; q[0][0] = 1, q[0][1] = 1, q[0][2] = 3; q[1][0] = 2, q[1][1] = 1, q[1][2] = 2; q[2][0] = 1, q[2][1] = 2, q[2][2] = 5; q[3][0] = 1, q[3][1] = 4, q[3][2] = 5; set<int> s; for (int i = 1; i < n; i++) { // Inserting indexes in the set of elements that are greater than 1. if (nums[i] > 1) s.insert(i); update_q(i, nums[i], n); } for (int i = 0; i < no_query; i++) { // Checking 0th index for update query or sum query. if (q[i][0] == 2) { while (true) { // Finding the left index using binary search auto it = s.lower_bound(q[i][1]); // checking whether it reaches right index. if (it == s.end() || *it > q[i][2]) break; q[i][1] = *it; // updating array element to their square roots. update_q(*it, (int)sqrt(nums[*it]) - nums[*it], n); nums[*it] = (int)sqrt(nums[*it]); //checking if updated value is 1 the removing it from set if (nums[*it] == 1) s.erase(*it); q[i][1]++; } } else { cout <<"query" << i+1 <<": " << (sum_q(q[i][2]) - sum_q(q[i][1] - 1)) << endl; } } return 0; }
Output
query1: 14 query3: 10 query4: 7
Conclusion
In this tutorial, we discussed the range sum query and range update query for the array. We discussed a simple approach to solve this problem and an efficient approach by using Binary Indexed Tree. We also discussed the C++ program for this problem which we can do with programming languages like C, Java, Python, etc. We hope you find this tutorial helpful.
- Related Articles
- Binary Indexed Tree: Range Update and Range Queries in C++
- Range Sum Queries Without Updates using C++
- C++ Program to count square root cube root and both in given range
- Queries to update a given index and find gcd in range in C++
- C++ Program for Range sum queries without updates?
- Queries to update a given index and find gcd in range in C++ Program
- C++ Program for the Range sum queries without updates?
- Square and Square root in Arduino
- What is square root and cube root?
- MySQL queries to update date records with NULL values
- Find the Initial Array from given array after range sum queries in C++
- Replace Odd Numbers with Square root & Even Numbers with Square in Java
- Queries to find maximum product pair in range with updates in C++
- 8086 program to find the square root of a perfect square root number
- Array range queries for elements with frequency same as value in C Program?
