Range sum queries for anticlockwise rotations of Array by K indices
Last Updated :
25 Apr, 2023
Given an array arr consisting of N elements and Q queries of the following two types:
- 1 K: For this type of query, the array needs to be rotated by K indices anticlockwise from its current state.
- 2 L R: For this query, the sum of the array elements present in the indices [L, R] needs to be calculated.
Example:
Input: arr = { 1, 2, 3, 4, 5, 6 }, query = { {2, 1, 3}, {1, 3}, {2, 0, 3}, {1, 4}, {2, 3, 5} }
Output:
9
16
12
Explanation:
For the 1st query {2, 1, 3} -> Sum of the elements in the indices [1, 3] = 2 + 3 + 4 = 9.
For the 2nd query {1, 3} -> Modified array after anti-clockwise rotation by 3 places is { 4, 5, 6, 1, 2, 3 }
For the 3rd query {2, 0, 3} -> Sum of the elements in the indices [0, 3] = 4 + 5 + 6 + 1 = 16.
For the 4th query {1, 4} -> Modified array after anti-clockwise rotation by 4 places is { 2, 3, 4, 5, 6, 1 }
For the 5th query {2, 3, 5} -> Sum of the elements in the indices [3, 5] = 5 + 6 + 1 = 12.
Approach:
- Create a prefix array which is double the size of the arr and copy the element at the ith index of arr to ith and N + ith index of prefix for all i in [0, N).
- Precompute the prefix sum for every index of that array and store in prefix.
- Set the pointer start at 0 to denote the starting index of the initial array.
- For query of type 1, shift start to
((start + K) % N)th position
- For query of type 2, calculate
prefix[start + R]
- prefix[start + L- 1 ]
- if start + L >= 1 or print the value of
prefix[start + R]
Below code is the implementation of the above approach:
C++
// C++ Program to calculate range sum
// queries for anticlockwise
// rotations of array by K
#include <bits/stdc++.h>
using namespace std;
// Function to execute the queries
void rotatedSumQuery(
int arr[], int n,
vector<vector<int> >& query,
int Q)
{
// Construct a new array
// of size 2*N to store
// prefix sum of every index
int prefix[2 * n];
// Copy elements to the new array
for (int i = 0; i < n; i++) {
prefix[i] = arr[i];
prefix[i + n] = arr[i];
}
// Calculate the prefix sum
// for every index
for (int i = 1; i < 2 * n; i++)
prefix[i] += prefix[i - 1];
// Set start pointer as 0
int start = 0;
for (int q = 0; q < Q; q++) {
// Query to perform
// anticlockwise rotation
if (query[q][0] == 1) {
int k = query[q][1];
start = (start + k) % n;
}
// Query to answer range sum
else if (query[q][0] == 2) {
int L, R;
L = query[q][1];
R = query[q][2];
// If pointing to 1st index
if (start + L == 0)
// Display the sum upto start + R
cout << prefix[start + R] << endl;
else
// Subtract sum upto start + L - 1
// from sum upto start + R
cout << prefix[start + R]
- prefix[start + L - 1]
<< endl;
}
}
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
// Number of query
int Q = 5;
// Store all the queries
vector<vector<int> > query
= { { 2, 1, 3 },
{ 1, 3 },
{ 2, 0, 3 },
{ 1, 4 },
{ 2, 3, 5 } };
int n = sizeof(arr) / sizeof(arr[0]);
rotatedSumQuery(arr, n, query, Q);
return 0;
}
Java
// Java program to calculate range sum
// queries for anticlockwise
// rotations of array by K
class GFG{
// Function to execute the queries
static void rotatedSumQuery(int arr[], int n,
int [][]query, int Q)
{
// Construct a new array
// of size 2*N to store
// prefix sum of every index
int []prefix = new int[2 * n];
// Copy elements to the new array
for(int i = 0; i < n; i++)
{
prefix[i] = arr[i];
prefix[i + n] = arr[i];
}
// Calculate the prefix sum
// for every index
for(int i = 1; i < 2 * n; i++)
prefix[i] += prefix[i - 1];
// Set start pointer as 0
int start = 0;
for(int q = 0; q < Q; q++)
{
// Query to perform
// anticlockwise rotation
if (query[q][0] == 1)
{
int k = query[q][1];
start = (start + k) % n;
}
// Query to answer range sum
else if (query[q][0] == 2)
{
int L, R;
L = query[q][1];
R = query[q][2];
// If pointing to 1st index
if (start + L == 0)
// Display the sum upto start + R
System.out.print(prefix[start + R] + "\n");
else
// Subtract sum upto start + L - 1
// from sum upto start + R
System.out.print(prefix[start + R] -
prefix[start + L - 1] +
"\n");
}
}
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
// Number of query
int Q = 5;
// Store all the queries
int [][]query = { { 2, 1, 3 },
{ 1, 3 },
{ 2, 0, 3 },
{ 1, 4 },
{ 2, 3, 5 } };
int n = arr.length;
rotatedSumQuery(arr, n, query, Q);
}
}
// This code is contributed by Rohit_ranjan
Python3
# Python3 program to calculate range sum
# queries for anticlockwise
# rotations of the array by K
# Function to execute the queries
def rotatedSumQuery(arr, n, query, Q):
# Construct a new array
# of size 2*N to store
# prefix sum of every index
prefix = [0] * (2 * n)
# Copy elements to the new array
for i in range(n):
prefix[i] = arr[i]
prefix[i + n] = arr[i]
# Calculate the prefix sum
# for every index
for i in range(1, 2 * n):
prefix[i] += prefix[i - 1];
# Set start pointer as 0
start = 0;
for q in range(Q):
# Query to perform
# anticlockwise rotation
if (query[q][0] == 1):
k = query[q][1]
start = (start + k) % n;
# Query to answer range sum
elif (query[q][0] == 2):
L = query[q][1]
R = query[q][2]
# If pointing to 1st index
if (start + L == 0):
# Display the sum upto start + R
print(prefix[start + R])
else:
# Subtract sum upto start + L - 1
# from sum upto start + R
print(prefix[start + R]-
prefix[start + L - 1])
# Driver code
arr = [ 1, 2, 3, 4, 5, 6 ];
# Number of query
Q = 5
# Store all the queries
query= [ [ 2, 1, 3 ],
[ 1, 3 ],
[ 2, 0, 3 ],
[ 1, 4 ],
[ 2, 3, 5 ] ]
n = len(arr);
rotatedSumQuery(arr, n, query, Q);
# This code is contributed by ankitkumar34
C#
// C# program to calculate range sum
// queries for anticlockwise
// rotations of array by K
using System;
class GFG{
// Function to execute the queries
static void rotatedSumQuery(int[] arr, int n,
int[,] query, int Q)
{
// Construct a new array
// of size 2*N to store
// prefix sum of every index
int[] prefix = new int[2 * n];
// Copy elements to the new array
for(int i = 0; i < n; i++)
{
prefix[i] = arr[i];
prefix[i + n] = arr[i];
}
// Calculate the prefix sum
// for every index
for(int i = 1; i < 2 * n; i++)
prefix[i] += prefix[i - 1];
// Set start pointer as 0
int start = 0;
for(int q = 0; q < Q; q++)
{
// Query to perform
// anticlockwise rotation
if (query[q, 0] == 1)
{
int k = query[q, 1];
start = (start + k) % n;
}
// Query to answer range sum
else if (query[q, 0] == 2)
{
int L, R;
L = query[q, 1];
R = query[q, 2];
// If pointing to 1st index
if (start + L == 0)
// Display the sum upto start + R
Console.Write(prefix[start + R] + "\n");
else
// Subtract sum upto start + L - 1
// from sum upto start + R
Console.Write(prefix[start + R] -
prefix[start + L - 1] +
"\n");
}
}
}
// Driver code
public static void Main()
{
int[] arr = new int[] { 1, 2, 3, 4, 5, 6 };
// Number of query
int Q = 5;
// Store all the queries
int[,] query = new int[,] { { 2, 1, 3 },
{ 1, 3, 0 },
{ 2, 0, 3 },
{ 1, 4, 0 },
{ 2, 3, 5 } };
int n = arr.Length;
rotatedSumQuery(arr, n, query, Q);
}
}
// This code is contributed by sanjoy_62
JavaScript
<script>
// Javascript program to calculate range sum
// queries for anticlockwise
// rotations of array by K
// Function to execute the queries
function rotatedSumQuery(arr, n,
query, Q)
{
// Construct a new array
// of size 2*N to store
// prefix sum of every index
let prefix = [];
// Copy elements to the new array
for(let i = 0; i < n; i++)
{
prefix[i] = arr[i];
prefix[i + n] = arr[i];
}
// Calculate the prefix sum
// for every index
for(let i = 1; i < 2 * n; i++)
prefix[i] += prefix[i - 1];
// Set start pointer as 0
let start = 0;
for(let q = 0; q < Q; q++)
{
// Query to perform
// anticlockwise rotation
if (query[q][0] == 1)
{
let k = query[q][1];
start = (start + k) % n;
}
// Query to answer range sum
else if (query[q][0] == 2)
{
let L, R;
L = query[q][1];
R = query[q][2];
// If pointing to 1st index
if (start + L == 0)
// Display the sum upto start + R
document.write(prefix[start + R] + "<br/>");
else
// Subtract sum upto start + L - 1
// from sum upto start + R
document.write(prefix[start + R] -
prefix[start + L - 1] +
"<br/>");
}
}
}
// Driver code
let arr = [ 1, 2, 3, 4, 5, 6 ];
// Number of query
let Q = 5;
// Store all the queries
let query = [[ 2, 1, 3 ],
[ 1, 3 ],
[ 2, 0, 3 ],
[ 1, 4 ],
[ 2, 3, 5 ]];
let n = arr.length;
rotatedSumQuery(arr, n, query, Q);
// This code is contributed by susmitakundugoaldanga.
</script>
Time Complexity: O(N+Q), where Q is the number of queries, and as each query will cost O (1) time for Q queries time complexity would be O(N+Q).
Auxiliary Space: O(N), as we are using extra space for prefix.
Similar Reads
Javascript Program for Range sum queries for anticlockwise rotations of Array by K indices Given an array arr consisting of N elements and Q queries of the following two types: 1 K: For this type of query, the array needs to be rotated by K indices anticlockwise from its current state.2 L R: For this query, the sum of the array elements present in the indices [L, R] needs to be calculated
4 min read
Count of Ks in the Array for a given range of indices after array updates for Q queries Given an array arr[] of N integers, an integer K, and Q queries of the type as explained below: (1, L, R): If the query is of type 1, then find the number of Ks over the range [L, R].(2, P, X): If the query is of type 2, then update the array element at index P to X. The task is to perform the queri
15+ min read
Reversal algorithm for right rotation of an array Given an array, right rotate it by k elements. After K=3 rotation Examples: Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} k = 3 Output: 8 9 10 1 2 3 4 5 6 7 Input: arr[] = {121, 232, 33, 43 ,5} k = 2 Output: 43 5 121 232 33 Note : In the below solution, k is assumed to be smaller than or equal to n
6 min read
Quickly find multiple left rotations of an array | Set 1 Given an array of size n and multiple values around which we need to left rotate the array. How to quickly find multiple left rotations? Examples: Input: arr[] = {1, 3, 5, 7, 9} k1 = 1 k2 = 3 k3 = 4 k4 = 6Output: 3 5 7 9 1 7 9 1 3 5 9 1 3 5 7 3 5 7 9 1 Input: arr[] = {1, 3, 5, 7, 9} k1 = 14 Output:
15 min read
Queries for rotation and Kth character of the given string in constant time Given a string str, the task is to perform the following type of queries on the given string: (1, K): Left rotate the string by K characters.(2, K): Print the Kth character of the string. Examples: Input: str = "abcdefgh", q[][] = {{1, 2}, {2, 2}, {1, 4}, {2, 7}} Output: d e Query 1: str = "cdefghab
6 min read
Count of possible remainders for K in given ranges for Q queries Given an array arr[ ] which contains N positive integers and an integer K and a vector of queries Q . Two types of queries can be asked: In the type 1 query, all elements from index l to r are increased by value X. The input format of this query: 1 l r xIn the type 2 query, for a given integer K pri
15+ min read