Open In App

Queries on Left and Right Circular shift on array

Given an array arr[] of N integers. There are three types of commands: 

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
Explanation: 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.

Input: N = 5, arr[] = { 1, 2, 3, 4, 5 }
query 1 = { 2, 1 }
query 2 = { 3, 0, 2 }
query 3 = { 1, 3 }
query 4 = { 3, 1, 4 }
Output: 9, 11 
Explanation:
Initial array arr[] = { 1, 2, 3, 4, 5 } 
After query 1, arr[] = {2, 3, 4, 5, 1 }
After query 2, sum from index 0 to index 2 is 9. 
So output 9.
After query 3, arr[] = { 4, 5, 1, 2, 3}
After query 4, sum from index 1 to index 4 is 11. 
So output 11.

Approach 1 (Brute Approach): The basic idea is as follows:

For each type of query, perform the mentioned task. In each query either do left rotation, or right rotation or find the sum of the elements in the given range.

Time Complexity: O(N * Q) where Q is the number of queries.
Auxiliary Space: O(1)

Approach 2 (Efficient Approach): The approach is based on the concept of prefix sum and array rotation as follows:

Initially the array is not rotated. So, calculate the net rotation of the array. A negative net rotation means right rotation and positive net rotation means left rotation. Whenever there is a query asking for the sum of a range provide the sum of the elements that will be in that range after the net rotation till that index.

Follow the below steps to implement the idea:

Follow the below illustration for a better understanding:

Illustration:

Initial array arr[] = { 1, 2, 3, 4, 5 } and the queries are
query 1 = {2, 1}
query 2 = {3, 0, 2}
query 3 = {1, 3}
query 4 = {3, 1, 4}

The prefixsum[] = { 1, 3, 6, 10, 15 } 

query 1 = {2, 1}: 
        => Net rotation = 1

query 2 = { 3, 0, 2 }: 
        => Net rotation = 1
        => Say l = 0, r = 2.
        => Value of l in original order = 1 and r in original order = 3.
        => Therefore, the sum = 10 – 1 = 9.

query 3 = {1, 3}:
        => Net rotation = 1 – 3 = -2

query 4 = {3, 1, 4}:
        => Net rotation = -2
        => Say l = 1, r = 4.
        => Value of l in original order = (1 – 2 + 5)%5 = 4
        => Value of r in original order = (4 – 2 + 5)%5 = 2
        => The sum = (15 – 10) + 6 = 11

Below is the implementation of the above approach:  




// 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 Program
int main()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    int N = sizeof(arr) / sizeof(arr[0]);
    wrapper(arr, N);
    return 0;
}




// Java Program to solve queries on Left and Right
// Circular shift on array
import java.io.*;
 
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)
            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 arr[] = { 1, 2, 3, 4, 5 };
        int N = arr.length;
        wrapper(arr, 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 Program
if __name__ == '__main__':
    arr = [ 1, 2, 3, 4, 5 ]
    N = len(arr)
    wrapper(arr, N)
 
# This code is contributed by rohan07.




// C# Program to solve queries on Left and Right
// Circular shift on array
using 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[] arr = { 1, 2, 3, 4, 5 };
        int N = arr.Length;
        wrapper(arr, 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 Program
let arr = [ 1, 2, 3, 4, 5 ]
let N = arr.length
wrapper(arr, N)
 
// This code is contributed by rohan07.
</script>

Output
12
11

Time Complexity: O(N)
Auxiliary Space: O(N)


Article Tags :