📅  最后修改于: 2023-12-03 15:25:11             🧑  作者: Mango
给定一个数组和若干个查询,每个查询包含一个数 x 和两个整数 l,r。对于每个查询,求出 l<=i<=r 且 arr[i] 与 x 的异或值。
第一行包含一个整数 n,表示数组长度。
第二行包含 n 个整数,表示数组中的元素。
接下来一行包含一个整数 q,表示查询个数。
接下来 q 行,每行包含一个整数 x 和两个整数 l,r,表示一次查询的具体范围。
对于每个询问,输出一个整数,表示对于每个查询,求出 l<=i<=r 且 arr[i] 与 x 的异或值。
输入样例:
6
1 2 3 4 5 6
3
2 2 4
3 1 3
4 4 6
输出样例:
1
2
2
该题需要对每个查询进行处理,对于每个查询 x 和区间 [l, r],需要求出数组 arr[] 中,与给定数 x 异或后,在区间 [l, r] 内元素异或的结果。
在暴力解法的基础上可以采用线段树进行优化,线段树节点记录的信息为当前区间内所有元素的异或结果。每次查询时,递归询问线段树,将查询区间一分为二,分别对左右区间进行递归,直到查询区间与线段树节点区间重叠,此时判断节点所代表的区间与查询区间是否完全重合,若重合,则返回该节点记录的异或结果,否则继续递归。
class SegmentTree:
def __init__(self, data):
self.l = 0
self.r = len(data) - 1
self.data = data
self.tree = [0] * 4 * len(data)
self.build(0, self.l, self.r)
def build(self, node, l, r):
if (l == r):
self.tree[node] = self.data[l]
return
mid = (l + r) >> 1
self.build(node*2+1, l, mid)
self.build(node*2+2, mid+1, r)
self.tree[node] = self.tree[node*2+1] ^ self.tree[node*2+2]
def query(self, l, r, x):
return self._query(0, self.l, self.r, l-1, r-1, x)
def _query(self, node, l, r, ql, qr, x):
if r < ql or l > qr:
return 0
if ql <= l and r <= qr:
return self.tree[node] ^ x
mid = (l + r) >> 1
res1 = self._query(node*2+1, l, mid, ql, qr, x)
res2 = self._query(node*2+2, mid+1, r, ql, qr, x)
return res1 ^ res2
if __name__ == "__main__":
n = int(input().strip())
data = list(map(int, input().split()))
st = SegmentTree(data)
q = int(input().strip())
for _ in range(q):
x, l, r = map(int, input().split())
print(st.query(l, r, x))
该算法的时间复杂度约为 O(nlogn),其中 n 代表序列中元素的个数。
该算法的空间复杂度约为 O(nlogn),其中 n 代表序列中元素的个数。