这里考虑维护的信息。
考虑维护区间众数出现次数,维护区间最值。
这里使用了 Mo's algorithm 和 SparseTable。
。
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 2.5E5;
int sum[N + 1], z[N + 1];
template <class T, typename F = function<T(T, T)>>
struct SparseTable {
int n;
vector<vector<T>> a;
F func;
SparseTable(const vector<T> &init, const F f) : n(init.size()), func(f) {
int lg = __lg(n);
a.assign(lg + 1, vector<T>(n));
a[0] = init;
for (int i = 1; i <= lg; i++) {
for (int j = 0; (1 << (i - 1)) + j < n; j++) {
a[i][j] = func(a[i - 1][j], a[i - 1][(1 << (i - 1)) + j]);
}
}
}
T get(int l, int r) { // [l, r)
int lg = __lg(r - l);
return func(a[lg][l], a[lg][r - (1 << lg)]);
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
SparseTable<int> mx(a, [&](int x, int y) {
return max(x, y);
});
SparseTable<int> mn(a, [&](int x, int y){
return min(x, y);
});
vector<array<int, 3>> qry(q);
for (int i = 0; i < q; i++) {
auto &[l, r, j] = qry[i];
cin >> l >> r;
l--, j = i; // [l, r)
}
int bk = n / sqrt(q);
sort(qry.begin(), qry.end(), [&](const auto &a, const auto &b) {
return ((a[0] / bk) ^ (b[0] / bk))
? a[0] < b[0]
: (((a[0] / bk) & 1) ? a[1] < b[1] : a[1] > b[1]);
});
int l = 0, r = 0, res = 0;
vector<string> ans(q);
auto add = [&](int j) {
int x = a[j];
sum[z[x]]--, z[x]++, sum[z[x]]++;
res = max(res, z[x]);
};
auto del = [&](int j) {
int x = a[j];
if (z[x] == res && sum[z[x]] == 1) {
res--;
}
sum[z[x]]--, z[x]--, sum[z[x]]++;
};
for (int i = 0; i < q; i++) {
auto &[ql, qr, qi] = qry[i];
while (r < qr) add(r++);
while (l > ql) add(--l);
while (l < ql) del(l++);
while (r > qr) del(--r);
int mx0 = mx.get(ql, qr), mn0 = mn.get(ql, qr), len = qr - ql;
ans[qi] = "Yes";
if (len % 2 || mx0 != len / 2 || mn0 != 1 || res != 2) {
ans[qi] = "No";
}
}
for (int i = 0; i < q; i++) {
cout << ans[i] << '\n';
}
return 0;
}