关于数组左右循环移位的查询

给定一个数组 A. 属于 N 整数。有三种类型的命令:

null
  • 1 x: 右循环移动数组x次。如果数组是[0]、[1]、…。,a[n-1],然后在一个右循环移位后,数组将变成[n-1]、a[0]、a[1]、…。,a[n-2]。
  • 2 y: 向左循环移动数组y次。如果数组是[0]、[1]、…。,a[n–1],然后在左循环移位一次后,数组将变成[1]…。,a[n-2],a[n-1],a[0]。
  • 3 l r: 打印子数组a[l…r](包括l和r)中所有整数的总和。

鉴于 Q 查询时,任务是执行每个查询。

例如:

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         11Initial 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.

方法1:(暴力) 实现三个函数,rotateR(arr,k)将数组arr向右旋转k次,rotateL(arr,k)将数组arr向左旋转k次,sum(arr,l,r)将数组arr的和从索引l输出到索引r。在输入值1,2,3时调用相应的函数。

方法2:(有效方法) 最初,没有旋转,我们有许多查询要求在一个范围内的整数总和。 我们可以计算数组中所有元素的前缀和, 前缀[i] 将表示到第i个索引的所有整数之和。 现在,如果我们想找到两个索引,即l和r之间的元素之和,我们只需计算prefixsum[r]–prefixsum[l–1]就可以在固定时间内计算它。 现在轮换,如果我们为每个查询轮换数组,效率会非常低。 我们只需要跟踪网络旋转。如果跟踪数字为负数,则表示左旋转占主导地位,否则右旋转占主导地位。当我们追踪网络旋转时,我们需要 mod n .与每旋转n次一样,阵列将恢复到其原始状态。 我们需要以这样一种方式观察它:每次旋转数组时,只有它的索引在变化。 如果我们需要回答任何第三种类型的查询,我们有l和r,我们需要找到l和r的原始顺序。我们可以通过将净旋转数加到索引中并取mod n来很容易地找到它。 每个命令都可以在O(1)时间内执行。

下面是C++实现这种方法:

C++

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


Python3

# 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
a = [ 1 , 2 , 3 , 4 , 5 ]
n = len (a)
wrapper(a, n)
# This code is contributed by rohan07.


Javascript

<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 a = [ 1, 2, 3, 4, 5 ]
let n = a.length
wrapper(a, n)
// This code is contributed by rohan07.
</script>


输出:

1211

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享