给定一个数组arr[]和Q查询,任务是在 Q 查询后找到结果更新的数组。有两种类型的查询,由它们执行以下操作:
- Update(L, R, K):对L到R范围内的每个元素与K进行异或。
- Display():显示给定数组的当前状态。
例子:
Input: arr[] = {1, 2, 3, 4, 5, 6}, Q = 2
Query 1: Update(1, 5, 3)
Query 2: Display()
Output: 2 1 0 7 6 6
Explanation:
The update query performs XOR of all elements in the range [1, 5].
After performing the update query, the above array is displayed for display query because:
1 ^ 3 = 2
2 ^ 3 = 1
3 ^ 3 = 0
4 ^ 3 = 7
5 ^ 3 = 6
Input: arr[] = {2, 4, 6, 8, 10}, Q = 3
Query 1: Update(1, 3, 2)
Query 2: Update(2, 4, 3)
Query 3: Display()
Output: 0 5 7 11 10
Explanation:
There are two update queries.
After performing the first update query, the given array is changed to {0, 6, 4, 8, 10}. This is because:
2 ^ 2 = 0
4 ^ 2 = 6
6 ^ 2 = 4
After obtaining this array, this array further gets changed for the second query as the {0, 5, 7, 11, 10}. This is because:
6 ^ 3 = 5
4 ^ 3 = 7
8 ^ 3 = 11
朴素的方法:这个问题的朴素的方法是对于每个更新查询,从 L 到 R 运行一个循环,并使用给定的 K 与从 arr[L] 到 arr[R] 的所有元素执行 XOR 操作。为了执行显示查询,只需打印数组 arr[]。这种方法的时间复杂度是 O(NQ),其中 N 是数组的长度,Q 是查询的数量。
有效的方法:这个想法是使用 kadane 算法来解决这个问题。
- 一个空数组 res[] 被定义为与原始数组具有相同的长度。
- 对于每个更新查询 {L, R, K}, res[] 数组被修改为:
- XOR K 到 res[L]
- XOR K 到 res[R + 1]
- 每当用户给出显示查询时:
- 将计数器变量“i”初始化为索引 1。
- 执行操作:
res[i] = res[i] ^ res[i - 1]
- 将计数器变量“i”初始化为索引 0。
- 对于数组中的每个索引,所需的答案是:
arr[i] ^ res[i]
下面是上述方法的实现:
C++
// C++ implementation to perform the
// XOR range updates on an array
#include
using namespace std;
// Function to perform the update operation
// on the given array
void update(int res[], int L, int R, int K)
{
// Converting the indices to
// 0 indexing.
L -= 1;
R -= 1;
// Saving the XOR of K from the starting
// index in the range [L, R].
res[L] ^= K;
// Saving the XOR of K at the ending index
// in the given [L, R].
res[R + 1] ^= K;
}
// Function to display the resulting array
void display(int arr[], int res[], int n)
{
for (int i = 1; i < n; i++) {
// Finding the resultant value in the
// result array
res[i] = res[i] ^ res[i - 1];
}
for (int i = 0; i < n; i++) {
// Combining the effects of the updates
// with the original array without
// changing the initial array.
cout << (arr[i] ^ res[i]) << " ";
}
cout << endl;
}
// Driver code
int main()
{
int arr[] = { 2, 4, 6, 8, 10 };
int N = sizeof(arr) / sizeof(arr[0]);
int res[N];
memset(res, 0, sizeof(res));
// Query 1
int L = 1, R = 3, K = 2;
update(res, L, R, K);
// Query 2
L = 2;
R = 4;
K = 3;
update(res, L, R, K);
// Query 3
display(arr, res, N);
return 0;
}
Java
// Java implementation to perform the
// XOR range updates on an array
class GFG{
// Function to perform the update
// operation on the given array
static void update(int res[], int L,
int R, int K)
{
// Converting the indices to
// 0 indexing.
L -= 1;
R -= 1;
// Saving the XOR of K from the
// starting index in the range [L, R].
res[L] ^= K;
// Saving the XOR of K at the ending
// index in the given [L, R].
res[R + 1] ^= K;
}
// Function to display the resulting array
static void display(int arr[],
int res[], int n)
{
int i;
for(i = 1; i < n; i++)
{
// Finding the resultant value
// in the result array
res[i] = res[i] ^ res[i - 1];
}
for(i = 0; i < n; i++)
{
// Combining the effects of the
// updates with the original array
// without changing the initial array.
System.out.print((arr[i] ^ res[i]) + " ");
}
System.out.println();
}
// Driver code
public static void main(String []args)
{
int arr[] = { 2, 4, 6, 8, 10 };
int N = arr.length;
int res[] = new int[N];
// Query 1
int L = 1, R = 3, K = 2;
update(res, L, R, K);
// Query 2
L = 2;
R = 4;
K = 3;
update(res, L, R, K);
// Query 3
display(arr, res, N);
}
}
// This code is contributed by chitranayal
Python3
# Python3 implementation to perform the
# XOR range updates on an array
# Function to perform the update operation
# on the given array
def update(res, L, R, K):
# Converting the indices to
# 0 indexing.
L = L - 1
R = R - 1
# Saving the XOR of K from the starting
# index in the range [L, R].
res[L] = res[L] ^ K
# Saving the XOR of K at the ending index
# in the given [L, R].
res[R + 1] = res[R + 1] ^ K
# Function to display the resulting array
def display(arr, res, n):
for i in range(1, n):
# Finding the resultant value in the
# result array
res[i] = res[i] ^ res[i - 1]
for i in range(0, n):
# Combining the effects of the updates
# with the original array without
# changing the initial array.
print (arr[i] ^ res[i], end = " ")
# Driver code
arr = [ 2, 4, 6, 8, 10 ]
N = len(arr)
res = [0] * N
# Query 1
L = 1
R = 3
K = 2
update(res, L, R, K)
# Query 2
L = 2
R = 4
K = 3
update(res, L, R, K)
# Query 3
display(arr, res, N)
# This code is contributed by Pratik Basu
C#
// C# implementation to perform the
// XOR range updates on an array
using System;
class GFG{
// Function to perform the update
// operation on the given array
static void update(int []res, int L,
int R, int K)
{
// Converting the indices to
// 0 indexing.
L -= 1;
R -= 1;
// Saving the XOR of K from the
// starting index in the range [L, R].
res[L] ^= K;
// Saving the XOR of K at the ending
// index in the given [L, R].
res[R + 1] ^= K;
}
// Function to display the resulting array
static void display(int []arr,
int []res, int n)
{
int i;
for(i = 1; i < n; i++)
{
// Finding the resultant value
// in the result array
res[i] = res[i] ^ res[i - 1];
}
for(i = 0; i < n; i++)
{
// Combining the effects of the
// updates with the original array
// without changing the initial array.
Console.Write((arr[i] ^ res[i]) + " ");
}
Console.WriteLine();
}
// Driver code
public static void Main()
{
int []arr = { 2, 4, 6, 8, 10 };
int N = arr.Length;
int []res = new int[N];
// Query 1
int L = 1, R = 3, K = 2;
update(res, L, R, K);
// Query 2
L = 2;
R = 4;
K = 3;
update(res, L, R, K);
// Query 3
display(arr, res, N);
}
}
// This code is contributed by Code_Mech
Javascript
0 5 7 11 10
时间复杂度:
- 更新的时间复杂度为O(1) 。
- 显示数组的时间复杂度为O(N) 。
注意:与显示查询相比,当更新查询非常高时,此方法非常有效。
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live