题目:
给你一个待查数组 queries ,数组中的元素为 1 到 m 之间的正整数。 请你根据以下规则处理所有待查项 queries[i](从 i=0 到 i=queries.length-1):
- 一开始,排列
P=[1,2,3,...,m]。 - 对于当前的
i,请你找出待查项queries[i]在排列P中的位置(下标从 0 开始),然后将其从原位置移动到排列P的起始位置(即下标为 0 处)。注意,queries[i]在P中的位置就是queries[i]的查询结果。
请你以数组形式返回待查数组 queries 的查询结果。
算法:
方法一:树状数组
构造树状数组BIT 0|[1,n]|[n+1, m]。
初始状态,1~m填充在BIT[n+1, m]区间,每次查询一个数,将该数移动到BIT[1,n]区间内。查询n次共移动n次。所求ans[i]即i左侧有多少个数字。
另外需要用一个数组pos,维护qureies[i]在BIT中的位置。
func processQueries(queries []int, m int) []int {
n := len(queries)
BIT = make([]int, m + n + 1)
ans := make([]int, n)
// pos[val]=index, 维护[1,m]的元素val在BIT数组中的index
pos := make([]int, m + 1)
for i := 1; i <= m; i ++ {
pos[i] = n + i
add(n + i, 1)
}
for i := 0; i < n; i ++ {
// queries[i] -> val -> BIT的index
index := pos[queries[i]]
// ans[i] = get[index]
ans[i] = get(index - 1)
// update(index, - 1)
add(index, -1)
// 更新pos
index = n - i
pos[queries[i]] = index
// update(index2, 1)
add(index, 1)
}
return ans
}
var BIT []int
func get(i int) int {
ans := 0
for i > 0 {
ans = ans + BIT[i]
i = i - lowBit(i)
}
return ans
}
func lowBit(x int) int {
return x & (-x)
}
func add(i, v int) {
for i < len(BIT) {
BIT[i] = BIT[i] + v
i = i + lowBit(i)
}
}