📌  相关文章
📜  范围和查询以K索引逆时针旋转Array

📅  最后修改于: 2021-05-14 01:26:00             🧑  作者: Mango

给定一个数组arr ,该数组arrN个元素和以下两种类型的Q个查询组成:

  • 1 K :对于这种类型的查询,阵列需要从其当前状态逆时针旋转K个索引。
  • 2 LR :对于此查询,需要计算索引[L,R]中存在的数组元素的总和。

例子:

方法:

  • 创建前缀阵列ARR的两倍大小和ARR索引复制元件在iiN + I前缀索引对于所有的i在[0,N)。
  • 为该数组的每个索引预先计算前缀和,并将其存储在prefix中
  • 将指针起始位置设置为0,以表示初始数组的起始索引。
  • 对于类型1的查询时,移位开始
((start + K) % N)th position
  • 对于类型2的查询,计算
prefix[start + R]
 - prefix[start + L- 1 ]
  • 如果start + L> = 1或打印
prefix[start + R]
  • 除此以外。

下面的代码是上述方法的实现:

C++
// C++ Program to calculate range sum
// queries for anticlockwise
// rotations of array by K
 
#include 
using namespace std;
 
// Function to execute the queries
void rotatedSumQuery(
    int arr[], int n,
    vector >& 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 > 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


输出:
9
16
12

时间复杂度:每个查询为O(1)
辅助空间复杂度: O(N)