📅  最后修改于: 2023-12-03 14:58:37.177000             🧑  作者: Mango
门|门CS 2011 |第 39 题
有一个长度为 $n$ 的由正整数构成的序列 $a_{1}, a_{2}, …, a_{n}$。定义一个数 $x$ 的值为在这个序列中小于等于 $x$ 的数的个数。现在请你编写一个查询系统,它能回答下面两种类型的询问:
1、询问 $[l,r]$ 中有多少个不同的数。
2、询问 $[l,r]$ 中有多少个数的值在 $[a,b]$ 之间。
对于第一种询问,我们可以使用 set 或 unordered_set 保存区间中所有数的值。最后返回 set/unordered_set 的大小即可。
对于第二种询问,可以使用前缀和的方式预处理出 $\text{value}[i]$ 即数值为 $i$ 的数的个数,然后用前缀和的方式求出 $\text{value}[i]$ 在区间 $[l, r]$ 中的和即为存在于 $[l, r]$ 中的值在区间 $[a, b]$ 中的个数。
#include <bits/stdc++.h>
using namespace std;
vector<int> a;
int n;
int mn, mx;
vector<int> pos[100005];
vector<int> value(100005, 0);
template<typename T>
vector<size_t> sort_indexes(const vector<T> &v) {
vector<size_t> idx(v.size());
iota(idx.begin(), idx.end(), 0);
stable_sort(idx.begin(), idx.end(),
[&v](const size_t i, const size_t j) { return v[i] < v[j]; });
return idx;
}
void init() { // 预处理信息
cin >> n >> mn >> mx;
a.resize(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
pos[a[i]].push_back(i);
value[a[i]]++;
}
for (int i = 1; i <= mx; i++) {
value[i] += value[i - 1];
}
}
void query1() {
unordered_set<int> S;
int l, r;
cin >> l >> r;
for (int i = l; i <= r; i++) {
S.insert(a[i]);
}
cout << S.size() << "\n";
}
void query2() {
int l, r, ai, bi;
cin >> l >> r >> ai >> bi;
cout << (value[bi] - value[ai - 1]) - (lower_bound(pos[bi].begin(), pos[bi].end(), r + 1) -
lower_bound(pos[bi].begin(), pos[bi].end(), l))
<< "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
init();
int m;
cin >> m;
while (m--) {
int type;
cin >> type;
if (type == 1) {
query1();
} else {
query2();
}
}
return 0;
}
### 题目描述
[门|门CS 2011 |第 39 题](https://www.luogu.com.cn/problem/P2030)
有一个长度为 $n$ 的由正整数构成的序列 $a_{1}, a_{2}, …, a_{n}$。定义一个数 $x$ 的值为在这个序列中小于等于 $x$ 的数的个数。现在请你编写一个查询系统,它能回答下面两种类型的询问:
1、询问 $[l,r]$ 中有多少个不同的数。
2、询问 $[l,r]$ 中有多少个数的值在 $[a,b]$ 之间。
### 解题思路
对于第一种询问,我们可以使用 set 或 unordered_set 保存区间中所有数的值。最后返回 set/unordered_set 的大小即可。
对于第二种询问,可以使用前缀和的方式预处理出 $\text{value}[i]$ 即数值为 $i$ 的数的个数,然后用前缀和的方式求出 $\text{value}[i]$ 在区间 $[l, r]$ 中的和即为存在于 $[l, r]$ 中的值在区间 $[a, b]$ 中的个数。
### 代码示例
```cpp
{
code snippet here
}