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.

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]

    otherwise.

Below code is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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;
}

chevron_right


Python 3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


Output:

9
16
12

Time Complexity: O(1) for every query.
Auxilary Space Complexity: O(N)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : ANKITKUMAR34