c++ sparsetable 模版
闭区间查询
支持
区间最大
区间最小
区间和
区间最大下标
区间最小下标
#include <bits/stdc++.h>
using namespace std;#ifndef NO_UNIQUE_ADDRESS
# ifdef __has_cpp_attribute
# if __has_cpp_attribute(no_unique_address)
# define NO_UNIQUE_ADDRESS [[no_unique_address]]
# endif
# endif
# ifndef NO_UNIQUE_ADDRESS
# define NO_UNIQUE_ADDRESS
# endif
#endif // !NO_UNIQUE_ADDRESSnamespace details {inline unsigned int bsf32(uint32_t n) noexcept {
#if defined __GNUC__return __builtin_ctz(n);
#elif defined _MSC_VERunsigned long ans;_BitScanForward(&ans, n);return ans;
#elifstatic constexpr unsigned char table[32] = {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,};return table[((n & -n) * 0x077CB531) >> 57];
#endif}inline unsigned int bsf64(uint64_t n) noexcept {
#if defined __GNUC__return __builtin_ctzll(n);
#elif defined _MSC_VERunsigned long ans;_BitScanForward64(&ans, n);return ans;
#elifstatic constexpr unsigned char table[64] = {0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,};return table[((n & -n) * 0x03f79d71b4ca8b09) >> 58];
#endif}inline unsigned int bsr32(uint32_t n) noexcept {
#if defined __GNUC__return 31 - __builtin_clz(n);
#elif defined _MSC_VERunsigned long ans;_BitScanReverse(&ans, n);return ans;
#eliffloat t = n;uint32_t ans;memcpy(&ans, &t, sizeof(float));return (ans >> 23 & 255) - 127;
#endif}inline unsigned int bsr64(uint64_t n) noexcept {
#if defined __GNUC__return 63 - __builtin_clzll(n);
#elif defined _MSC_VERunsigned long ans;_BitScanReverse64(&ans, n);return ans;
#eliffloat t = n;uint32_t ans;memcpy(&ans, &t, sizeof(float));return (ans >> 23 & 255) - 127;
#endif}inline unsigned int popcnt32(uint32_t n) noexcept {
#if defined __GNUC__return __builtin_popcount(n);
#elif defined _MSC_VERreturn __popcnt(n);
#elifn -= ((n >> 1) & 0x55555555);n = (n & 0x33333333) + ((n >> 2) & 0x33333333);return ((((n >> 4) + n) & 0x0f0f0f0f) * 0x01010101) >> 24;
#endif}inline unsigned int popcnt64(uint64_t n) noexcept {
#if defined __GNUC__return __builtin_popcountll(n);
#elif defined _MSC_VERreturn __popcnt64(n);
#elifn -= ((n >> 1) & 0x5555555555555555);n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);return ((((n >> 4) + n) & 0x0f0f0f0f0f0f0f0f) * 0x0101010101010101) >> 56;
#endif}inline unsigned int parity32(uint32_t n) noexcept {
#if defined __GNUC__return __builtin_parity(n);
#elif defined _MSC_VERreturn __popcnt(n) & 1;
#elifn ^= n >> 1;n ^= n >> 2;n = (n & 0x11111111) * 0x11111111;return (n >> 28) & 1;
#endif}inline unsigned int parity64(uint64_t n) noexcept {
#if defined __GNUC__return __builtin_parityll(n);
#elif defined _MSC_VERreturn __popcnt64(n) & 1;
#elifn ^= n >> 1;n ^= n >> 2;n = (n & 0x1111111111111111) * 0x1111111111111111;return (n >> 60) & 1;
#endif}template<typename I, bool B = 32 < std::numeric_limits<I>::digits>struct _BitFuncImpl {inline static unsigned int bsf(I n) noexcept { return bsf64(n); }inline static unsigned int bsr(I n) noexcept { return bsr64(n); }inline static unsigned int popcnt(I n) noexcept { return popcnt64(n); }inline static unsigned int parity(I n) noexcept { return parity64(n); }};template<typename I>struct _BitFuncImpl<I, false> {inline static unsigned int bsf(I n) noexcept { return bsf32(n); }inline static unsigned int bsr(I n) noexcept { return bsr32(n); }inline static unsigned int popcnt(I n) noexcept { return popcnt32(n); }inline static unsigned int parity(I n) noexcept { return parity32(n); }};template<typename I>inline unsigned int bsf(I n) noexcept { return _BitFuncImpl<I>::bsf(n); }template<typename I>inline unsigned int bsr(I n) noexcept { return _BitFuncImpl<I>::bsr(n); }template<typename I>inline unsigned int popcnt(I n) noexcept { return _BitFuncImpl<I>::popcnt(n); }template<typename I>inline unsigned int parity(I n) noexcept { return _BitFuncImpl<I>::parity(n); }template<typename T, size_t K = 0, bool = std::is_empty<T>::value && !std::is_final<T>::value>struct Derivable {private:T val;public:constexpr Derivable() = default;template<typename... Args>constexpr Derivable(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args&&...>::value) : val(std::forward<Args>(args)...) {}inline constexpr T& value() noexcept { return val; }inline constexpr const T& value() const noexcept { return val; }};template<typename T, size_t K>struct Derivable<T, K, true> : private T {constexpr Derivable() = default;template<typename... Args>constexpr Derivable(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args&&...>::value) : T(std::forward<Args>(args)...) {}inline constexpr T& value() noexcept { return *this; }inline constexpr const T& value() const noexcept { return *this; }};template<typename Alloc>struct InitializerIterator {using traits = std::allocator_traits<Alloc>;using pointer = typename traits::pointer;using value_type = typename traits::value_type;InitializerIterator(const InitializerIterator&) = delete;InitializerIterator(InitializerIterator&& other) noexcept: ptr(other.ptr), cur(other.cur), p_alloc(other.p_alloc){other.ptr = other.cur = nullptr;other.p_alloc = nullptr;}InitializerIterator(pointer ptr, Alloc& alloc) noexcept : ptr(ptr), cur(ptr), p_alloc(&alloc) {}~InitializerIterator() noexcept {if (!std::is_trivially_destructible<value_type>::value)for (pointer it = ptr;it != cur;++it)traits::destroy(*p_alloc, std::addressof(*it));}inline pointer release() noexcept {return ptr = cur;}inline InitializerIterator& operator*() noexcept { return *this; }inline InitializerIterator& operator++() noexcept { return *this; }inline InitializerIterator& operator++(int) noexcept { return *this; }InitializerIterator& operator=(const InitializerIterator&) = delete;InitializerIterator& operator=(InitializerIterator&& other) noexcept {ptr = other.ptr;cur = other.cur;p_alloc = other.p_alloc;other.ptr = other.cur = nullptr;other.p_alloc = nullptr;return *this;}template<typename T>inline InitializerIterator& operator=(T&& val) noexcept(noexcept(std::is_nothrow_constructible<value_type, T&&>::value)) {traits::construct(*p_alloc, std::addressof(*cur), std::forward<T>(val));++cur;return *this;}private:pointer ptr, cur;Alloc* p_alloc;};
}template<typename TableIt, typename OutIt, typename Op>
inline OutIt make_sparse_table(TableIt st, size_t n, OutIt it, const Op& op = {}) {TableIt pre = std::move(st);for (size_t i = 2;i <= n;i *= 2) {for (size_t j = 0;j <= n - i;++j)*it++ = op(pre[j], pre[j + i / 2]);pre += n + 1 - i / 2;}return std::move(it);
}inline size_t sparse_table_size(size_t n) {const size_t h = details::bsr(n) + size_t(1);return n * h + h + size_t(1) - (size_t(1) << h);
}template<typename TableIt, typename Op>
inline typename std::iterator_traits<TableIt>::value_type query_sparse_table(TableIt st, size_t n, size_t l, size_t r, const Op& op = {}) {assert(l <= r && r < n);r++;const size_t h = details::bsr(r - l), ph = size_t(1) << h;const auto row = st + (n * h + h + 1 - ph);return op(row[l], row[r - ph]);
}template<typename It, typename Op>
class SparseTableView {
public:using value_type = typename std::iterator_traits<It>::value_type;using size_type = unsigned;using operator_type = Op;protected:It st;size_type n;NO_UNIQUE_ADDRESS operator_type op;public:SparseTableView(It it, size_type n, const operator_type& op = {}) : st(std::move(it)), n(n), op(op) {}inline size_type size() const noexcept {return n;}// 闭区间inline value_type query(size_type l, size_type r) const {return query_sparse_table(st, n, l, r, op);}// 闭区间inline value_type query(size_type l, size_type r, const value_type& unitary) const {return r <= l ? unitary : query(l, r);}
};template<typename T, typename Op>
class SparseTable : protected SparseTableView<T*, Op> {
private:using base_type = SparseTableView<T*, Op>;public:using typename base_type::value_type;using typename base_type::size_type;using typename base_type::operator_type;using pointer = value_type*;using reference = value_type&;using const_pointer = const value_type*;using const_reference = const value_type&;private:using allocator_type = std::allocator<value_type>;using allocator_traits = std::allocator_traits<allocator_type>;inline const operator_type& operator_() const noexcept {return this->op;}inline static allocator_type& allocator() noexcept {static allocator_type alloc{};return alloc;}struct Guard {pointer ptr;size_type len;~Guard() { if (len > 0) allocator_traits::deallocate(allocator(), ptr, len); }};inline void clean() noexcept {if (this->n > 0) {const size_type st_size = sparse_table_size(this->n);if (!std::is_trivially_destructible<value_type>::value) {const pointer end = this->st + st_size;for (pointer it = this->st;it != end;++it)allocator_traits::destroy(allocator(), it);}allocator_traits::deallocate(allocator(), this->st, st_size);}}public:template<typename It>SparseTable(It it, size_type n, const Op& op = {}): base_type(nullptr, n, op){if (n == 0) return;const size_type st_size = sparse_table_size(n);Guard guard = {allocator_traits::allocate(allocator(), st_size), st_size};details::InitializerIterator<allocator_type> initializer(guard.ptr, allocator());for (size_type i = 0;i < n;++i, ++it)*initializer++ = *it;make_sparse_table(guard.ptr, n, std::move(initializer), operator_()).release();this->st = guard.ptr;guard.len = 0;}template<typename S>SparseTable(const S& seq, const Op& op = {}) : SparseTable(seq.begin(), seq.size(), op) {}SparseTable(const SparseTable&) = delete;SparseTable(SparseTable&& other) noexcept: base_type(std::move(other)){other.st = nullptr;other.n = 0;}SparseTable& operator=(const SparseTable&) = delete;SparseTable& operator=(SparseTable&& other) noexcept {clean();base_type::operator=(std::move(other));other.st = nullptr;other.n = 0;return *this;}~SparseTable() {clean();}inline void clear() noexcept {clean();this->st = nullptr;this->n = 0;}inline SparseTableView<const_pointer, Op> view() const {return SparseTableView<const_pointer, Op>(this->st, this->n, this->op);}using base_type::size;using base_type::query;
};class Solution {
public:struct MAX {int operator()(int x, int y) const noexcept {return std::max(x, y);}};vector<int> maxSlidingWindow(vector<int>& nums, int k) {SparseTable<int, MAX> st(nums);vector<int> ans;for (size_t i = 0, n = nums.size(); i + k <= n; ++i)ans.push_back(st.query(i, i + k - 1)); // 调整为闭区间return ans;}
};template<typename T>
struct MAX {T operator()(T x, T y) const noexcept {return std::max(x, y);}
};template<typename T>
struct MIN {T operator()(T x, T y) const noexcept {return std::min(x, y);}
};template<typename T>
struct SUM {T operator()(T x, T y) const noexcept {return x + y;}
};struct MaxIndex {const vector<int>& nums;MaxIndex(const vector<int>& nums) : nums(nums) {}int operator()(int i, int j) const noexcept {return nums[i] >= nums[j] ? i : j;}
};struct MinIndex {const vector<int>& nums;MinIndex(const vector<int>& nums) : nums(nums) {}int operator()(int i, int j) const noexcept {return nums[i] <= nums[j] ? i : j;}
};template<typename T>
struct SparseTableMaxIndex {MaxIndex max_index;vector<int> indices;SparseTable<T, MaxIndex> max_st;SparseTableMaxIndex(const vector<int>& nums) : max_index(nums), indices(nums.size()),max_st((iota(indices.begin(), indices.end(), 0), indices), max_index) {}T query(int l, int r) const {return max_st.query(l, r);}
};template<typename T>
struct SparseTableMinIndex {MinIndex min_index;vector<int> indices;SparseTable<T, MinIndex> min_st;SparseTableMinIndex(const vector<int>& nums) : min_index(nums), indices(nums.size()),min_st((iota(indices.begin(), indices.end(), 0), indices), min_index) {}T query(int l, int r) const {return min_st.query(l, r);}
};template<typename T>
using SparseTableSum = SparseTable<T, SUM<T>>;template<typename T>
using SparseTableMax = SparseTable<T, MAX<T>>;template<typename T>
using SparseTableMin = SparseTable<T, MIN<T>>;int main() {vector<int> nums = {1, -1, 4, 7};// 闭区间查询SparseTableMaxIndex<int> st(nums);for (int i = 0; i < 4; i++) {for (int j = i; j <= 4; j++) {cout << st.query(i, j) << " "; // 调整为闭区间}cout << endl;}
}
#include <bits/stdc++.h>
using namespace std;#ifndef NO_UNIQUE_ADDRESS
# ifdef __has_cpp_attribute
# if __has_cpp_attribute(no_unique_address)
# define NO_UNIQUE_ADDRESS [[no_unique_address]]
# endif
# endif
# ifndef NO_UNIQUE_ADDRESS
# define NO_UNIQUE_ADDRESS
# endif
#endif // !NO_UNIQUE_ADDRESSnamespace details {inline unsigned int bsf32(uint32_t n) noexcept {
#if defined __GNUC__return __builtin_ctz(n);
#elif defined _MSC_VERunsigned long ans;_BitScanForward(&ans, n);return ans;
#elifstatic constexpr unsigned char table[32] = {0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,};return table[((n & -n) * 0x077CB531) >> 57];
#endif}inline unsigned int bsf64(uint64_t n) noexcept {
#if defined __GNUC__return __builtin_ctzll(n);
#elif defined _MSC_VERunsigned long ans;_BitScanForward64(&ans, n);return ans;
#elifstatic constexpr unsigned char table[64] = {0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,};return table[((n & -n) * 0x03f79d71b4ca8b09) >> 58];
#endif}inline unsigned int bsr32(uint32_t n) noexcept {
#if defined __GNUC__return 31 - __builtin_clz(n);
#elif defined _MSC_VERunsigned long ans;_BitScanReverse(&ans, n);return ans;
#eliffloat t = n;uint32_t ans;memcpy(&ans, &t, sizeof(float));return (ans >> 23 & 255) - 127;
#endif}inline unsigned int bsr64(uint64_t n) noexcept {
#if defined __GNUC__return 63 - __builtin_clzll(n);
#elif defined _MSC_VERunsigned long ans;_BitScanReverse64(&ans, n);return ans;
#eliffloat t = n;uint32_t ans;memcpy(&ans, &t, sizeof(float));return (ans >> 23 & 255) - 127;
#endif}inline unsigned int popcnt32(uint32_t n) noexcept {
#if defined __GNUC__return __builtin_popcount(n);
#elif defined _MSC_VERreturn __popcnt(n);
#elifn -= ((n >> 1) & 0x55555555);n = (n & 0x33333333) + ((n >> 2) & 0x33333333);return ((((n >> 4) + n) & 0x0f0f0f0f) * 0x01010101) >> 24;
#endif}inline unsigned int popcnt64(uint64_t n) noexcept {
#if defined __GNUC__return __builtin_popcountll(n);
#elif defined _MSC_VERreturn __popcnt64(n);
#elifn -= ((n >> 1) & 0x5555555555555555);n = (n & 0x3333333333333333) + ((n >> 2) & 0x3333333333333333);return ((((n >> 4) + n) & 0x0f0f0f0f0f0f0f0f) * 0x0101010101010101) >> 56;
#endif}inline unsigned int parity32(uint32_t n) noexcept {
#if defined __GNUC__return __builtin_parity(n);
#elif defined _MSC_VERreturn __popcnt(n) & 1;
#elifn ^= n >> 1;n ^= n >> 2;n = (n & 0x11111111) * 0x11111111;return (n >> 28) & 1;
#endif}inline unsigned int parity64(uint64_t n) noexcept {
#if defined __GNUC__return __builtin_parityll(n);
#elif defined _MSC_VERreturn __popcnt64(n) & 1;
#elifn ^= n >> 1;n ^= n >> 2;n = (n & 0x1111111111111111) * 0x1111111111111111;return (n >> 60) & 1;
#endif}template<typename I, bool B = 32 < std::numeric_limits<I>::digits>struct _BitFuncImpl {inline static unsigned int bsf(I n) noexcept { return bsf64(n); }inline static unsigned int bsr(I n) noexcept { return bsr64(n); }inline static unsigned int popcnt(I n) noexcept { return popcnt64(n); }inline static unsigned int parity(I n) noexcept { return parity64(n); }};template<typename I>struct _BitFuncImpl<I, false> {inline static unsigned int bsf(I n) noexcept { return bsf32(n); }inline static unsigned int bsr(I n) noexcept { return bsr32(n); }inline static unsigned int popcnt(I n) noexcept { return popcnt32(n); }inline static unsigned int parity(I n) noexcept { return parity32(n); }};template<typename I>inline unsigned int bsf(I n) noexcept { return _BitFuncImpl<I>::bsf(n); }template<typename I>inline unsigned int bsr(I n) noexcept { return _BitFuncImpl<I>::bsr(n); }template<typename I>inline unsigned int popcnt(I n) noexcept { return _BitFuncImpl<I>::popcnt(n); }template<typename I>inline unsigned int parity(I n) noexcept { return _BitFuncImpl<I>::parity(n); }template<typename T, size_t K = 0, bool = std::is_empty<T>::value && !std::is_final<T>::value>struct Derivable {private:T val;public:constexpr Derivable() = default;template<typename... Args>constexpr Derivable(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args&&...>::value) : val(std::forward<Args>(args)...) {}inline constexpr T& value() noexcept { return val; }inline constexpr const T& value() const noexcept { return val; }};template<typename T, size_t K>struct Derivable<T, K, true> : private T {constexpr Derivable() = default;template<typename... Args>constexpr Derivable(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args&&...>::value) : T(std::forward<Args>(args)...) {}inline constexpr T& value() noexcept { return *this; }inline constexpr const T& value() const noexcept { return *this; }};template<typename Alloc>struct InitializerIterator {using traits = std::allocator_traits<Alloc>;using pointer = typename traits::pointer;using value_type = typename traits::value_type;InitializerIterator(const InitializerIterator&) = delete;InitializerIterator(InitializerIterator&& other) noexcept: ptr(other.ptr), cur(other.cur), p_alloc(other.p_alloc){other.ptr = other.cur = nullptr;other.p_alloc = nullptr;}InitializerIterator(pointer ptr, Alloc& alloc) noexcept : ptr(ptr), cur(ptr), p_alloc(&alloc) {}~InitializerIterator() noexcept {if (!std::is_trivially_destructible<value_type>::value)for (pointer it = ptr;it != cur;++it)traits::destroy(*p_alloc, std::addressof(*it));}inline pointer release() noexcept {return ptr = cur;}inline InitializerIterator& operator*() noexcept { return *this; }inline InitializerIterator& operator++() noexcept { return *this; }inline InitializerIterator& operator++(int) noexcept { return *this; }InitializerIterator& operator=(const InitializerIterator&) = delete;InitializerIterator& operator=(InitializerIterator&& other) noexcept {ptr = other.ptr;cur = other.cur;p_alloc = other.p_alloc;other.ptr = other.cur = nullptr;other.p_alloc = nullptr;return *this;}template<typename T>inline InitializerIterator& operator=(T&& val) noexcept(noexcept(std::is_nothrow_constructible<value_type, T&&>::value)) {traits::construct(*p_alloc, std::addressof(*cur), std::forward<T>(val));++cur;return *this;}private:pointer ptr, cur;Alloc* p_alloc;};
}template<typename TableIt, typename OutIt, typename Op>
inline OutIt make_sparse_table(TableIt st, size_t n, OutIt it, const Op& op = {}) {TableIt pre = std::move(st);for (size_t i = 2;i <= n;i *= 2) {for (size_t j = 0;j <= n - i;++j)*it++ = op(pre[j], pre[j + i / 2]);pre += n + 1 - i / 2;}return std::move(it);
}inline size_t sparse_table_size(size_t n) {const size_t h = details::bsr(n) + size_t(1);return n * h + h + size_t(1) - (size_t(1) << h);
}template<typename TableIt, typename Op>
inline typename std::iterator_traits<TableIt>::value_type query_sparse_table(TableIt st, size_t n, size_t l, size_t r, const Op& op = {}) {const size_t h = details::bsr(r - l), ph = size_t(1) << h;const auto row = st + (n * h + h + 1 - ph);return op(row[l], row[r - ph]);
}template<typename It, typename Op>
class SparseTableView {
public:using value_type = typename std::iterator_traits<It>::value_type;using size_type = unsigned;using operator_type = Op;protected:It st;size_type n;NO_UNIQUE_ADDRESS operator_type op;public:SparseTableView(It it, size_type n, const operator_type& op = {}) : st(std::move(it)), n(n), op(op) {}inline size_type size() const noexcept {return n;}inline value_type query(size_type l, size_type r) const {return query_sparse_table(st, n, l, r, op);}inline value_type query(size_type l, size_type r, const value_type& unitary) const {return r <= l ? unitary : query(l, r);}
};template<typename T, typename Op>
class SparseTable : protected SparseTableView<T*, Op> {
private:using base_type = SparseTableView<T*, Op>;public:using typename base_type::value_type;using typename base_type::size_type;using typename base_type::operator_type;using pointer = value_type*;using reference = value_type&;using const_pointer = const value_type*;using const_reference = const value_type&;private:using allocator_type = std::allocator<value_type>;using allocator_traits = std::allocator_traits<allocator_type>;inline const operator_type& operator_() const noexcept {return this->op;}inline static allocator_type& allocator() noexcept {static allocator_type alloc{};return alloc;}struct Guard {pointer ptr;size_type len;~Guard() { if (len > 0) allocator_traits::deallocate(allocator(), ptr, len); }};inline void clean() noexcept {if (this->n > 0) {const size_type st_size = sparse_table_size(this->n);if (!std::is_trivially_destructible<value_type>::value) {const pointer end = this->st + st_size;for (pointer it = this->st;it != end;++it)allocator_traits::destroy(allocator(), it);}allocator_traits::deallocate(allocator(), this->st, st_size);}}public:template<typename It>SparseTable(It it, size_type n, const Op& op = {}): base_type(nullptr, n, op){if (n == 0) return;const size_type st_size = sparse_table_size(n);Guard guard = {allocator_traits::allocate(allocator(), st_size), st_size};details::InitializerIterator<allocator_type> initializer(guard.ptr, allocator());for (size_type i = 0;i < n;++i, ++it)*initializer++ = *it;make_sparse_table(guard.ptr, n, std::move(initializer), operator_()).release();this->st = guard.ptr;guard.len = 0;}template<typename S>SparseTable(const S& seq, const Op& op = {}) : SparseTable(seq.begin(), seq.size(), op) {}SparseTable(const SparseTable&) = delete;SparseTable(SparseTable&& other) noexcept: base_type(std::move(other)){other.st = nullptr;other.n = 0;}SparseTable& operator=(const SparseTable&) = delete;SparseTable& operator=(SparseTable&& other) noexcept {clean();base_type::operator=(std::move(other));other.st = nullptr;other.n = 0;return *this;}~SparseTable() {clean();}inline void clear() noexcept {clean();this->st = nullptr;this->n = 0;}inline SparseTableView<const_pointer, Op> view() const {return SparseTableView<const_pointer, Op>(this->st, this->n, this->op);}using base_type::size;using base_type::query;
};
相关文章:
c++ sparsetable 模版
闭区间查询 支持 区间最大 区间最小 区间和 区间最大下标 区间最小下标 #include <bits/stdc.h> using namespace std;#ifndef NO_UNIQUE_ADDRESS # ifdef __has_cpp_attribute # if __has_cpp_attribute(no_unique_address) # define NO_UNIQUE_…...
创建线程池和封装锁
封装一个锁 1.封装一个Mutex class Mutex{public:Mutex(pthread_mutex_t * lock):_lock(lock){}void Lock(){pthread_mutex_lock(_lock);}void unLock(){pthread_mutex_unlock(_lock);}~Mutex(){}private:pthread_mutex_t *_lock; };2.封装一个LockGuard class LockGuard{pub…...

易图讯军用VR三维电子沙盘系统
深圳易图讯军用VR三维电子沙盘系统是一种集成了虚拟现实(VR)技术、三维建模技术、大数据分析、实时动态更新以及高度安全可靠的综合性军事指挥平台。该系统通过高精度三维模型真实再现战场环境,为指挥员提供沉浸式体验和交互操作的可能性&…...

LeetCode讲解篇之70. 爬楼梯
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 爬楼梯有一个规律,爬到第n层楼梯的方法种数 爬到第n - 1层楼梯的方法种数 爬到第n - 1层楼梯的方法种数 也就是我们爬到第n层楼梯其实是从第n - 1层楼梯向上爬1层或者是n - 2层楼梯向上爬2层转换来…...

论文写作不再难,论文初稿快速成型法!
撰写论文是每个学者的必修课,我非常明白撰写论文的不易。撰写过程中会遇到各种困扰,如思路不清晰、论证不充分、语言表达不准确等。在这里以我的经验分享给大家一个能快速完成论文初稿的秘诀“AI导师写作”,希望能帮助还在为论文发愁的你。 …...
linux系统,监控进程运行状态并自动重启崩溃后的进程的多种方法
系统进程运行异常崩溃后,自动重启的方法 有的公司,会写monitor守护进程,监视各个进程的运行状态,异常时,自动重启,但是这种,通过一个进程 监护一个进程的做法,不太完美,…...

【JavaEE初阶】深入理解不同锁的意义,synchronized的加锁过程理解以及CAS的原子性实现(面试经典题);
前言 🌟🌟本期讲解关于锁的相关知识了解,这里涉及到高频面试题哦~~~ 🌈上期博客在这里:【JavaEE初阶】深入理解线程池的概念以及Java标准库提供的方法参数分析-CSDN博客 🌈感兴趣的小伙伴看一看小编主页&am…...

详解Redis分布式锁在SpringBoot的@Async方法中没锁住的坑
背景 Redis分布式锁很有用处,在秒杀、抢购、订单、限流特别是一些用到异步分布式并行处理任务时频繁的用到,可以说它是一个BS架构的应用中最高频使用的技术之一。 但是我们经常会碰到这样的一个问题,那就是我们都按照标准做了但有时运行着、…...

怎么做接口自动化测试
在分层测试的“金字塔”模型中,接口测试属于第二层服务集成测试范畴。相比UI层(主要是WEB或APP)自动化测试而言,接口自动化测试收益更大,且容易实现,维护成本低,有着更高的投入产出比࿰…...

网络编程(18)——使用asio协程实现并发服务器
十八、day18 到目前为止,我们以及学习了单线程同步/异步服务器、多线程IOServicePool和多线程IOThreadPool模型,今天学习如何通过asio协程实现并发服务器。 并发服务器有以下几种好处: 协程比线程更轻量,创建和销毁协程的开销较…...

Koa2项目实战2(路由管理、项目结构优化)
添加路由(处理不同的URL请求) 路由:根据不同的URL,调用对应的处理函数。 每一个接口服务,最核心的功能是:根据不同的URL请求,返回不同的数据。也就是调用不同的接口返回不同的数据。 在 Node…...

决战Linux操作系统
前言: 你是否也曾经为Linux所困扰过,在网上找的资料零零散散,是否学完Linux后还是懵懵懂懂,别怕,这篇博客是博主精心为你准备的,现在,就让我们一起来走进Linux的世界,决战Linux&…...
OceanBase 3.2.2 数据库问题处理记录
只记录OceanBase 数据库与OCP的异常处理,其它组件暂时不写录。 一、问题1: 说明:OMS 出现异常,无法访问(OB无法访问) OB数据库架构:1:1:1 原因:某一台OBserver因为内存问题,被服务器直接kill掉…...

HCIP--以太网交换安全(二)端口安全
端口安全 一、端口安全概述 1.1、端口安全概述:端口安全是一种网络设备防护措施,通过将接口学习的MAC地址设为安全地址防止非法用户通信。 1.2、端口安全原理: 类型 定义 特点 安全动态MAC地址 使能端口而未是能Stichy MAC功能是转换的…...

在 Windows 11 安卓子系统中安装 APK 的操作指南
这个软件好像不可以在纯android系统中使用(不知道是缺了什么),其他对于android的虚拟机要不缺少必要功能组件,要不性能过于低下。本方法致力于在带有谷歌框架WSA中运行该APK 在 Windows 11 安卓子系统中安装 APK 的操作指南 本指…...

[C语言] 函数详解:库函数与自定义函数
文章目录 函数的概念库函数和自定义函数库函数使用库函数示例常用库函数及头文件 自定义函数自定义函数的基本结构示例:实现两个数的求和函数自定义函数的好处 函数的返回值有返回值的函数无返回值的函数 函数的声明与调用声明函数在另一个文件中调用函数示例&#…...
0x11 科迈 RAS系统 Cookie验证越权漏洞
参考: 科迈 RAS系统 Cookie验证越权漏洞 | PeiQi文库 (wgpsec.org)免责声明 欢迎访问我的博客。以下内容仅供教育和信息用途: 合法性:我不支持或鼓励非法活动。请确保遵守法律法规。信息准确性:尽管我尽力提供准确的信息,但不保证其完全准确或适用。使用前请自行验证。风…...

MoonBit 双周报 Vol.57:AI助手功能增强、表达式优先级调整、JS 交互优化、标准库与实验库API多项更新!
2024-10-08 IDE更新 AI Codelens支持 /generate 和 /fix 命令 /generate 命令能够提供一个通用的用以生成代码的聊天界面。 /fix 命令能够读取当前函数的错误信息给出修复建议。 MoonBit更新 调整中缀表达式和if、match、loop、while、for、try表达式的优先级, 后者这些控制…...
element ui input textarea控制显示高度
样式代码 .testPage { position: absolute; left: 0; top: 0; right: 0; bottom: 0; display: flex; height: 100%; /* 控制输入框高度 */ .el-textarea { height: 90%; ::v-deep .el-textarea__inner { height: 90%; } } }...
Chromium 中chrome.downloads扩展接口c++
一、前端chrome.downloads 使用 chrome.downloads API 以编程方式启动、监控、操作和搜索下载内容。 权限 downloads 您必须在扩展程序清单中声明 "downloads" 权限,才能使用此 API。 {"name": "My extension",..."permiss…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...