class RangeFreqQuery {
public:
RangeFreqQuery(vector<int>& arr) {
}
int query(int left, int right, int value) {
}
};
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* RangeFreqQuery* obj = new RangeFreqQuery(arr);
* int param_1 = obj->query(left,right,value);
*/
use std::collections::HashMap;
struct RangeFreqQuery {
pos: HashMap<i32, Vec<usize>>,
}
impl RangeFreqQuery {
fn new(arr: Vec<i32>) -> Self {
let mut pos = HashMap::new();
for (i, &x) in arr.iter().enumerate() {
pos.entry(x).or_insert(vec![]).push(i);
}
Self { pos }
}
fn query(&self, left: i32, right: i32, value: i32) -> i32 {
if let Some(a) = self.pos.get(&value) {
let p = a.partition_point(|&i| i < left as usize);
let q = a.partition_point(|&i| i <= right as usize);
(q - p) as _
} else {
0
}
}
}
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* let obj = RangeFreqQuery::new(arr);
* let ret_1: i32 = obj.query(left, right, value);
*/
class RangeFreqQuery {
private final Map<Integer, List<Integer>> pos = new HashMap<>();
public RangeFreqQuery(int[] arr) {
for (int i = 0; i < arr.length; i++) {
pos.computeIfAbsent(arr[i], k -> new ArrayList<>()).add(i);
}
}
public int query(int left, int right, int value) {
List<Integer> a = pos.get(value);
if (a == null) {
return 0;
}
// > right 等价于 >= right+1
return lowerBound(a, right + 1) - lowerBound(a, left);
}
// 开区间写法
// 请看 https://www.bilibili.com/video/BV1AP41137w7/
private int lowerBound(List<Integer> a, int target) {
// 开区间 (left, right)
int left = -1;
int right = a.size();
while (left + 1 < right) { // 区间不为空
// 循环不变量:
// a[left] < target
// a[right] >= target
int mid = (left + right) >>> 1;
if (a.get(mid) < target) {
left = mid; // 范围缩小到 (mid, right)
} else {
right = mid; // 范围缩小到 (left, mid)
}
}
return right; // right 是最小的满足 a[right] >= target 的下标
}
}
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* RangeFreqQuery obj = new RangeFreqQuery(arr);
* int param_1 = obj.query(left,right,value);
*/
class RangeFreqQuery {
unordered_map<int, vector<int>> pos;
public:
RangeFreqQuery(vector<int>& arr) {
for (int i = 0; i < arr.size(); i++) {
pos[arr[i]].push_back(i);
}
}
int query(int left, int right, int value) {
// 不推荐写 a = pos[value],如果 value 不在 pos 中会插入 value
auto it = pos.find(value);
if (it == pos.end()) {
return 0;
}
auto& a = it->second;
return ranges::upper_bound(a, right) - ranges::lower_bound(a, left);
}
};
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* RangeFreqQuery* obj = new RangeFreqQuery(arr);
* int param_1 = obj->query(left,right,value);
*/
type RangeFreqQuery struct{ pos [1e4 + 1]sort.IntSlice }
func Constructor(arr []int) (q RangeFreqQuery) {
for i, value := range arr {
q.pos[value] = append(q.pos[value], i) // 统计 value 在 arr 中的所有下标位置
}
return
}
func (q *RangeFreqQuery) Query(left, right, value int) int {
p := q.pos[value] // value 在 arr 中的所有下标位置
return p[p.Search(left):].Search(right + 1) // 在下标位置上二分,求 [left,right] 之间的下标个数,即为 value 的频率
}
/**
* Your RangeFreqQuery object will be instantiated and called as such:
* obj := Constructor(arr);
* param_1 := obj.Query(left,right,value);
*/
class RangeFreqQuery:
def __init__(self, arr: List[int]):
# 数值为键,出现下标数组为值的哈希表
self.occurence = defaultdict(list)
# 顺序遍历数组初始化哈希表
n = len(arr)
for i in range(n):
self.occurence[arr[i]].append(i)
def query(self, left: int, right: int, value: int) -> int:
# 查找对应的出现下标数组,不存在则为空
pos = self.occurence[value]
# 两次二分查找计算子数组内出现次数
l = bisect_left(pos, left)
r = bisect_right(pos, right)
return r - l
# Your RangeFreqQuery object will be instantiated and called as such:
# obj = RangeFreqQuery(arr)
# param_1 = obj.query(left,right,value)