Queries on Left and Right Circular shift on array

17 Jun, 2022
Given an array A of N integers. There are three types of commands: 
1 x : Right Circular Shift the array x times. If an array is a[0], a[1], ...., a[n – 1], then after one right circular shift the array will become a[n – 1], a[0], a[1], ...., a[n – 2].
2 y : Left Circular Shift the array y times. If an array is a[0], a[1], ...., a[n – 1], then after one left circular shift the array will become a[1], ...., a[n – 2], a[n – 1], a[0].
3 l r : Print the sum of all integers in the subarray a[l...r] (l and r inclusive).
Given Q queries, the task is to execute each query.
Examples:  
Input : n = 5, arr[] = { 1, 2, 3, 4, 5 }
        query 1 = { 1, 3 }
        query 2 = { 3, 0, 2 }
        query 3 = { 2, 1 }
        query 4 = { 3, 1, 4 }
Output : 12
         11
Initial array arr[] = { 1, 2, 3, 4, 5 }
After query 1, arr[] = { 3, 4, 5, 1, 2 }.
After query 2, sum from index 0 to index 
               2 is 12, so output 12.
After query 3, arr[] = { 4, 5, 1, 2, 3 }.
After query 4, sum from index 1 to index 
               4 is 11, so output 11.
Method 1 : (Brute Force)Implement three functions, rotateR(arr, k) which will right rotate array arr by k times, rotateL(arr, k) which will left rotate array arr by k times, sum(arr, l, r) which will output the sum of array arr from index l to index r. On the input of values 1, 2, and 3 call the appropriate function.
Method 2 : (Efficient Approach)Initially, there are no rotations and we have many queries asking for the sum of integers present in a range of indexes. We can evaluate the prefix sum of all elements in the array, prefixsum[i] will denote the sum of all the integers up to ith index. Now, if we want to find sum of elements between two indexes i.e l and r, we compute it in constant time by just calculating prefixsum[r] – prefixsum[l – 1]. Now for rotations, if we are rotating the array for every query, that will be highly inefficient. We just need to track the net rotation. If the tracked number is negative, it means left rotation has dominated else right rotation has dominated. When we are tracking the net rotations, we need to do mod n. After every n rotation, the array will return to its original state. We need to observe it in such a way that every time we rotate the array, only its indexes are changing. If we need to answer any query of third type and we have l and r. We need to find what l and r were in the original order. We can easily find it out by adding the net rotations to the index and taking mod n. Every command can be executed in O(1) time.
Below is C++ implementation of this approach:  
C++
Java
Python3
C#
Javascript
// C++ Program to solve queries on Left and Right// Circular shift on array#include <bits/stdc++.h>using namespace std; // Function to solve query of type 1 x.void querytype1(int* toRotate, int times, int n){    // Decreasing the absolute rotation    (*toRotate) = ((*toRotate) - times) % n;} // Function to solve query of type 2 y.void querytype2(int* toRotate, int times, int n){    // Increasing the absolute rotation.    (*toRotate) = ((*toRotate) + times) % n;} // Function to solve queries of type 3 l r.void querytype3(int toRotate, int l, int r,                      int preSum[], int n){    // Finding absolute l and r.    l = (l + toRotate + n) % n;    r = (r + toRotate + n) % n;     // if l is before r.    if (l <= r)        cout << (preSum[r + 1] - preSum[l]) << endl;        // If r is before l.    else        cout << (preSum[n] + preSum[r + 1] - preSum[l])             << endl;   } // Wrapper Function solve all queries.void wrapper(int a[], int n){    int preSum[n + 1];    preSum[0] = 0;     // Finding Prefix sum    for (int i = 1; i <= n; i++)        preSum[i] = preSum[i - 1] + a[i - 1];     int toRotate = 0;     // Solving each query    querytype1(&toRotate, 3, n);    querytype3(toRotate, 0, 2, preSum, n);    querytype2(&toRotate, 1, n);    querytype3(toRotate, 1, 4, preSum, n);} // Driver Programint main(){    int a[] = { 1, 2, 3, 4, 5 };    int n = sizeof(a) / sizeof(a[0]);    wrapper(a, n);    return 0;}
// Java Program to solve queries on Left and Right// Circular shift on arrayclass GFG {   // Function to solve query of type 1 x.  static int querytype1(int toRotate, int times, int n)  {         // Decreasing the absolute rotation    toRotate = (toRotate - times) % n;    return toRotate;  }   // Function to solve query of type 2 y.  static int querytype2(int toRotate, int times, int n) {    // Increasing the absolute rotation.    toRotate = (toRotate + times) % n;    return toRotate;  }   // Function to solve queries of type 3 l r.  static void querytype3(int toRotate, int l, int r,                         int preSum[], int n) {    // Finding absolute l and r.    l = (l + toRotate + n) % n;    r = (r + toRotate + n) % n;     // if l is before r.    if (l <= r)      System.out.println(preSum[r + 1] - preSum[l]);     // If r is before l.    else      System.out.println(preSum[n] + preSum[r + 1] - preSum[l]);  }   // Wrapper Function solve all queries.  static void wrapper(int a[], int n) {    int preSum[] = new int[n + 1];    preSum[0] = 0;     // Finding Prefix sum    for (int i = 1; i <= n; i++)      preSum[i] = preSum[i - 1] + a[i - 1];     int toRotate = 0;     // Solving each query    toRotate = querytype1(toRotate, 3, n);    querytype3(toRotate, 0, 2, preSum, n);    toRotate = querytype2(toRotate, 1, n);    querytype3(toRotate, 1, 4, preSum, n);  }   // Driver Program  public static void main(String args[]) {    int a[] = { 1, 2, 3, 4, 5 };    int n = a.length;    wrapper(a, n);  } } // This code is contributed by saurabh_jaiswal.
# Python Program to solve queries on Left and Right# Circular shift on array # Function to solve query of type 1 x.def querytype1(toRotate, times, n):       # Decreasing the absolute rotation    toRotate = (toRotate - times) % n    return toRotate # Function to solve query of type 2 y.def querytype2(toRotate, times, n):       # Increasing the absolute rotation.    toRotate = (toRotate + times) % n    return toRotate # Function to solve queries of type 3 l r.def querytype3( toRotate, l, r, preSum, n):       # Finding absolute l and r.    l = (l + toRotate + n) % n    r = (r + toRotate + n) % n     # if l is before r.    if (l <= r):        print((preSum[r + 1] - preSum[l]))       # If r is before l.    else:        print((preSum[n] + preSum[r + 1] - preSum[l])) # Wrapper Function solve all queries.def wrapper( a, n):    preSum = [ 0 for i in range(n + 1)]         # Finding Prefix sum    for i in range(1,n+1):        preSum[i] = preSum[i - 1] + a[i - 1]     toRotate = 0     # Solving each query    toRotate = querytype1(toRotate, 3, n)    querytype3(toRotate, 0, 2, preSum, n)    toRotate = querytype2(toRotate, 1, n)    querytype3(toRotate, 1, 4, preSum, n); # Driver Programa = [ 1, 2, 3, 4, 5 ]n = len(a)wrapper(a, n) # This code is contributed by rohan07.
// C# Program to solve queries on Left and Right// Circular shift on arrayusing System;class GFG{   // Function to solve query of type 1 x.  static int querytype1(int toRotate, int times, int n)  {     // Decreasing the absolute rotation    toRotate = (toRotate - times) % n;    return toRotate;  }   // Function to solve query of type 2 y.  static int querytype2(int toRotate, int times, int n)  {    // Increasing the absolute rotation.    toRotate = (toRotate + times) % n;    return toRotate;  }   // Function to solve queries of type 3 l r.  static void querytype3(int toRotate, int l, int r,                         int[] preSum, int n)  {    // Finding absolute l and r.    l = (l + toRotate + n) % n;    r = (r + toRotate + n) % n;     // if l is before r.    if (l <= r)      Console.WriteLine(preSum[r + 1] - preSum[l]);     // If r is before l.    else      Console.WriteLine(preSum[n] + preSum[r + 1] - preSum[l]);  }   // Wrapper Function solve all queries.  static void wrapper(int[] a, int n)  {    int[] preSum = new int[n + 1];    preSum[0] = 0;     // Finding Prefix sum    for (int i = 1; i <= n; i++)      preSum[i] = preSum[i - 1] + a[i - 1];     int toRotate = 0;     // Solving each query    toRotate = querytype1(toRotate, 3, n);    querytype3(toRotate, 0, 2, preSum, n);    toRotate = querytype2(toRotate, 1, n);    querytype3(toRotate, 1, 4, preSum, n);  }   // Driver Program  public static void Main()  {    int[] a = { 1, 2, 3, 4, 5 };    int n = a.Length;    wrapper(a, n);  } } // This code is contributed by _saurabh_jaiswal
<script> // JavaScript Program to solve queries on Left and Right// Circular shift on array // Function to solve query of type 1 x.function querytype1(toRotate, times, n){     // Decreasing the absolute rotation    toRotate = (toRotate - times) % n    return toRotate} // Function to solve query of type 2 y.function querytype2(toRotate, times, n){     // Increasing the absolute rotation.    toRotate = (toRotate + times) % n    return toRotate} // Function to solve queries of type 3 l r.function querytype3( toRotate, l, r, preSum, n){     // Finding absolute l and r.    l = (l + toRotate + n) % n    r = (r + toRotate + n) % n     // if l is before r.    if (l <= r)        document.write((preSum[r + 1] - preSum[l]),"</br>")     // If r is before l.    else        document.write((preSum[n] + preSum[r + 1] - preSum[l]),"</br>")} // Wrapper Function solve all queries.function wrapper(a, n){    preSum = new Array(n+1).fill(0)     // Finding Prefix sum    for(let i = 1; i <= n; i++)        preSum[i] = preSum[i - 1] + a[i - 1]     toRotate = 0     // Solving each query    toRotate = querytype1(toRotate, 3, n)    querytype3(toRotate, 0, 2, preSum, n)    toRotate = querytype2(toRotate, 1, n)    querytype3(toRotate, 1, 4, preSum, n);} // Driver Programlet a = [ 1, 2, 3, 4, 5 ]let n = a.lengthwrapper(a, n) // This code is contributed by rohan07.</script>
Output: 
12
11
Time Complexity: O(n).
Auxiliary Space: O(1) 
patnaikbhawna
rams2103
akshaysingh98088
siri1404
rohan07
shinjanpatra
_saurabh_jaiswal
codewithshinchan
triangleofcoding
array-range-queries
rotation
Arrays
Arrays
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.