算法
(莫队) $O(n\sqrt{q})$
本题依旧是普通莫队板题
可以先离散化一下,虽然用 std::map
也可以过
C++ 代码
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
// Coodinate Compression
template<typename T=int>
struct CC {
bool initialized;
vector<T> xs;
CC(): initialized(false) {}
void add(T x) { xs.push_back(x);}
void init() {
sort(xs.begin(), xs.end());
xs.erase(unique(xs.begin(),xs.end()),xs.end());
initialized = true;
}
int operator()(T x) {
if (!initialized) init();
return upper_bound(xs.begin(), xs.end(), x) - xs.begin() - 1;
}
T operator[](int i) {
if (!initialized) init();
return xs[i];
}
int size() {
if (!initialized) init();
return xs.size();
}
};
int main() {
cin.tie(nullptr) -> sync_with_stdio(false);
int n, q;
cin >> n >> q;
CC cc;
vector<int> a(n);
rep(i, n) {
cin >> a[i];
cc.add(a[i]);
}
rep(i, n) a[i] = cc(a[i]);
vector<int> l(q), r(q);
rep(i, q) cin >> l[i] >> r[i];
rep(i, q) l[i]--, r[i]--;
vector<int> qs(q);
iota(qs.begin(), qs.end(), 0);
const int D = n/sqrt(q)+1;
sort(qs.begin(), qs.end(), [&](int i, int j) {
if (r[i]/D == r[j]/D) return l[i] < l[j];
return r[i] < r[j];
});
vector<int> ans(q);
int nl = 0, nr = -1;
int now = 0;
vector<int> cnt(n);
auto add = [&](int i) {
now += cnt[a[i]] == 1;
now -= cnt[a[i]] == 2;
cnt[a[i]]++;
};
auto del = [&](int i) {
now += cnt[a[i]] == 3;
now -= cnt[a[i]] == 2;
cnt[a[i]]--;
};
for (int qi : qs) {
while (nl < l[qi]) del(nl), nl++;
while (nl > l[qi]) nl--, add(nl);
while (nr < r[qi]) nr++, add(nr);
while (nr > r[qi]) del(nr), nr--;
ans[qi] = now;
}
rep(i, q) cout << ans[i] << '\n';
return 0;
}