This documentation is automatically generated by online-judge-tools/verification-helper
#define PROBLEM "https://judge.yosupo.jp/problem/static_range_mode_query"
#include "../../Src/DataStructure/Mo/RollbackMo.hpp"
#include "../../Src/Sequence/CompressedSequence.hpp"
#include <iostream>
#include <utility>
#include <vector>
using namespace std;
using namespace zawa;
struct Query {
usize l, r;
};
struct Data {
int top = -1, last = -1;
};
int main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int N, Q;
cin >> N >> Q;
vector<int> A(N);
for (int i = 0 ; i < N ; i++)
cin >> A[i];
CompressedSequence<int> comp{A};
for (int i = 0 ; i < N ; i++)
A[i] = comp.map(i);
vector<Query> q(Q);
for (auto& [l, r] : q)
cin >> l >> r;
vector<int> cnt(ssize(comp));
auto add = [&](int i, Data d) {
cnt[A[i]]++;
if (d.top == -1 or cnt[A[i]] > cnt[d.top])
d.top = A[i];
d.last = A[i];
return d;
};
auto rollback = [&](const Data& d) {
cnt[d.last]--;
};
auto eval = [&](int, const Data& d) -> pair<int, int> {
return {comp.inverse(d.top), cnt[d.top]};
};
for (auto [a, b] : RollbackMo<Query, Data, decltype(add), decltype(rollback), decltype(eval)>(q, add, add, rollback, eval))
cout << a << ' ' << b << '\n';
}
#line 1 "Test/LC/static_range_mode_query.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/static_range_mode_query"
#line 2 "Src/DataStructure/Mo/RollbackMo.hpp"
#line 2 "Src/Template/TypeAlias.hpp"
#include <cstdint>
#include <cstddef>
namespace zawa {
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using usize = std::size_t;
} // namespace zawa
#line 4 "Src/DataStructure/Mo/RollbackMo.hpp"
#include <algorithm>
#include <cassert>
#include <concepts>
#include <limits>
#include <utility>
#include <vector>
namespace zawa {
template <class T, class RBT, class Add, class Rollback, class Eval>
std::vector<typename std::invoke_result_t<Eval, usize, const RBT&>> RollbackMo(const std::vector<T>& qs, Add addL, Add addR, Rollback rollback, Eval eval) {
const usize n = [&]() {
usize mx = 0;
for (usize i = 0 ; i < qs.size() ; i++) {
assert(qs[i].l <= qs[i].r);
mx = std::max<usize>(mx, qs[i].r);
}
return mx;
}();
const usize SQ = [&]() {
usize i = 1;
while (i * i < n)
i++;
return i;
}();
std::vector<std::vector<std::pair<usize, usize>>> rs((n + SQ - 1) / SQ);
std::vector<typename std::invoke_result_t<Eval, usize, const RBT&>> res(qs.size());
std::vector<RBT> history;
history.emplace_back();
for (usize i = 0 ; i < qs.size() ; i++) {
if (qs[i].r - qs[i].l <= SQ) {
for (usize j = qs[i].l ; j < qs[i].r ; j++)
history.push_back(addR(j, history.back()));
res[i] = eval(i, history.back());
for (usize j = qs[i].l ; j < qs[i].r ; j++) {
rollback(history.back());
history.pop_back();
}
}
else
rs[qs[i].l / SQ].emplace_back(qs[i].r, i);
}
for (usize i = 0 ; i < rs.size() ; i++)
if (rs[i].size()) {
std::sort(rs[i].begin(), rs[i].end());
const usize L = (i + 1) * SQ;
usize R = L;
for (auto [r, idx] : rs[i]) {
while (R < r)
history.push_back(addR(R++, history.back()));
for (usize j = L ; j > qs[idx].l ; )
history.push_back(addL(--j, history.back()));
res[idx] = eval(idx, history.back());
for (usize j = L ; j > qs[idx].l ; j--) {
rollback(history.back());
history.pop_back();
}
}
for (usize j = L ; j < R ; j++) {
rollback(history.back());
history.pop_back();
}
}
return res;
}
} // namespace zawa
#line 2 "Src/Sequence/CompressedSequence.hpp"
#line 4 "Src/Sequence/CompressedSequence.hpp"
#line 8 "Src/Sequence/CompressedSequence.hpp"
#include <iterator>
#line 10 "Src/Sequence/CompressedSequence.hpp"
namespace zawa {
template <class T>
class CompressedSequence {
public:
static constexpr u32 NotFound = std::numeric_limits<u32>::max();
CompressedSequence() = default;
template <class InputIterator>
CompressedSequence(InputIterator first, InputIterator last) : comped_(first, last), f_{} {
std::sort(comped_.begin(), comped_.end());
comped_.erase(std::unique(comped_.begin(), comped_.end()), comped_.end());
comped_.shrink_to_fit();
f_.reserve(std::distance(first, last));
for (auto it{first} ; it != last ; it++) {
f_.emplace_back(std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), *it)));
}
}
CompressedSequence(const std::vector<T>& A) : CompressedSequence(A.begin(), A.end()) {}
inline usize size() const noexcept {
return comped_.size();
}
u32 operator[](const T& v) const {
return std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), v));
}
u32 upper_bound(const T& v) const {
return std::distance(comped_.begin(), std::upper_bound(comped_.begin(), comped_.end(), v));
}
u32 find(const T& v) const {
u32 i = std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), v));
return i == comped_.size() or comped_[i] != v ? NotFound : i;
}
bool contains(const T& v) const {
u32 i = std::distance(comped_.begin(), std::lower_bound(comped_.begin(), comped_.end(), v));
return i < comped_.size() and comped_[i] == v;
}
u32 at(const T& v) const {
u32 res = find(v);
assert(res != NotFound);
return res;
}
inline u32 map(u32 i) const noexcept {
assert(i < f_.size());
return f_[i];
}
inline T inverse(u32 i) const noexcept {
assert(i < size());
return comped_[i];
}
inline std::vector<T> comped() const noexcept {
return comped_;
}
private:
std::vector<T> comped_;
std::vector<u32> f_;
};
} // namespace zawa
#line 5 "Test/LC/static_range_mode_query.test.cpp"
#include <iostream>
#line 9 "Test/LC/static_range_mode_query.test.cpp"
using namespace std;
using namespace zawa;
struct Query {
usize l, r;
};
struct Data {
int top = -1, last = -1;
};
int main() {
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
int N, Q;
cin >> N >> Q;
vector<int> A(N);
for (int i = 0 ; i < N ; i++)
cin >> A[i];
CompressedSequence<int> comp{A};
for (int i = 0 ; i < N ; i++)
A[i] = comp.map(i);
vector<Query> q(Q);
for (auto& [l, r] : q)
cin >> l >> r;
vector<int> cnt(ssize(comp));
auto add = [&](int i, Data d) {
cnt[A[i]]++;
if (d.top == -1 or cnt[A[i]] > cnt[d.top])
d.top = A[i];
d.last = A[i];
return d;
};
auto rollback = [&](const Data& d) {
cnt[d.last]--;
};
auto eval = [&](int, const Data& d) -> pair<int, int> {
return {comp.inverse(d.top), cnt[d.top]};
};
for (auto [a, b] : RollbackMo<Query, Data, decltype(add), decltype(rollback), decltype(eval)>(q, add, add, rollback, eval))
cout << a << ' ' << b << '\n';
}