package com.heu.wsq.leetcode.prefix_sum;
/**
* 1310. 子数组异或查询
* @author wsq
* @date 2021/5/12
* 有一个正整数数组 arr,现给你一个对应的查询数组 queries,其中 queries[i] = [Li, Ri]。
* 对于每个查询 i,请你计算从 Li 到 Ri 的 XOR 值(即 arr[Li] xor arr[Li+1] xor ... xor arr[Ri])作为本次查询的结果。
* 并返回一个包含给定查询 queries 所有结果的数组。
*
* 示例 1:
* 输入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
* 输出:[2,7,14,8]
* 解释:
* 数组中元素的二进制表示形式是:
* 1 = 0001
* 3 = 0011
* 4 = 0100
* 8 = 1000
* 查询的 XOR 值为:
* [0,1] = 1 xor 3 = 2
* [1,2] = 3 xor 4 = 7
* [0,3] = 1 xor 3 xor 4 xor 8 = 14
* [3,3] = 8
*
* 链接:https://leetcode-cn.com/problems/xor-queries-of-a-subarray
*/
public class XorQueries {
/**
* 类似前缀和的思想
* 1. 首先求得到达每个索引对应的前缀和的数组
* 2. 根据queries数组中元素项的起始位置和终止位置求得对应的范围的元素的异或值
* @param arr
* @param queries
* @return
*/
public int[] xorQueries(int[] arr, int[][] queries) {
if(arr == null || arr.length == 0){
return arr;
}
// 求得前缀异或值
int[] f = new int[arr.length];
f[0] = arr[0];
for(int i = 1; i < arr.length; i++){
f[i] = f[i - 1] ^ arr[i];
}
// 根据查询的左右索引获取对应范围的元素异或值
int n = queries.length;
int[] ans = new int[n];
for(int i = 0; i < n; i++){
int[] op = queries[i];
int left = op[0];
int right = op[1];
if(left == 0){
ans[i] = f[right];
}else{
ans[i] = f[right] ^ f[left - 1];
}
}
return ans;
}
}