add: 230323-CN

This commit is contained in:
Eatswap 2023-03-23 15:41:31 +08:00
parent 76787b7d48
commit 6b55e52a56
Signed by: Eatswap
GPG Key ID: BE661106A1F3FA0B
2 changed files with 109 additions and 1 deletions

108
cpp/2303/230323-CN.cpp Normal file
View File

@ -0,0 +1,108 @@
#include <vector>
#include <functional>
#include <iostream>
#include <unordered_map>
template<typename T>
class MinMaxSegTree {
private:
using V = std::vector<T>;
using OF = const T& (*)(const T&, const T&);
using BTF = std::function<T(int, int, int, const V&, V&, OF)>;
int n;
V s, b;
static constexpr inline int calc(int n) {
for (int i = 1; ; i <<= 1)
if (i >= n)
return i << 1;
}
T query(int L, int R, int qL, int qR, int pos, const V& tree, OF op) const {
if (L == qL && R == qR)
return tree[pos];
const int qM = (qL + qR) >> 1;
if (R <= qM)
return query(L, R, qL, qM, pos << 1, tree, op);
if (qM <= L)
return query(L, R, qM, qR, 1 | (pos << 1), tree, op);
return op(query(L, qM, qL, qM, pos << 1, tree, op), query(qM, R, qM, qR, 1 | (pos << 1), tree, op));
}
public:
explicit MinMaxSegTree(const std::vector<T>& d) : n(d.size()), s(calc(n)), b(calc(n)) {
BTF dfs = [&](int L, int R, int pos, const V& src, V& dst, OF op) {
if (L == R - 1)
return dst[pos] = src[L];
const int M = (L + R) >> 1;
return dst[pos] = op(dfs(L, M, pos << 1, src, dst, op), dfs(M, R, 1 | (pos << 1), src, dst, op));
};
dfs(0, n, 1, d, s, std::min);
dfs(0, n, 1, d, b, std::max);
}
T min(int L, int R) const {
return query(L, R, 0, n, 1, s, std::min);
}
T max(int L, int R) const {
return query(L, R, 0, n, 1, b, std::max);
}
};
/**
* 1630. Arithmetic Subarrays
*
* A sequence of numbers is called arithmetic if it consists of at least two elements, and the difference between every two consecutive elements is the same. More formally, a sequence s is arithmetic if and only if s[i+1] - s[i] == s[1] - s[0] for all valid i.
*
* For example, these are arithmetic sequences:
*
* 1, 3, 5, 7, 9
* 7, 7, 7, 7
* 3, -1, -5, -9
* The following sequence is not arithmetic:
*
* 1, 1, 2, 5, 7
* You are given an array of n integers, nums, and two arrays of m integers each, l and r, representing the m range queries, where the ith query is the range [l[i], r[i]]. All the arrays are 0-indexed.
*
* Return a list of boolean elements answer, where answer[i] is true if the subarray nums[l[i]], nums[l[i]+1], ... , nums[r[i]] can be rearranged to form an arithmetic sequence, and false otherwise.
*/
class Solution {
public:
static std::vector<bool> checkArithmeticSubarrays(
const std::vector<int>& nums,
const std::vector<int>& l,
const std::vector<int>& r
) {
auto tree = new MinMaxSegTree(nums);
const int n = l.size(), k = nums.size();
std::unordered_multimap<int, int> m;
for (int i = 0; i < k; ++i)
m.insert({nums[i], i});
std::vector<bool> ret(n);
for (int i = 0; i < n; ++i) {
const int L = l[i], R = r[i] + 1, min = tree->min(L, R), max = tree->max(L, R);
if ((max - min) % (R - L - 1))
continue;
int step = (max - min) / (R - L - 1);
bool OK = true;
for (int j = step + min; j < max; j += step) {
const auto [MERs, MERe] = m.equal_range(j);
if (!(OK = std::any_of(MERs, MERe, [L, R](auto&& x) { return x.second < R && x.second >= L; })))
break;
}
ret[i] = OK;
}
delete tree;
return ret;
}
};
int main() {
auto r = Solution::checkArithmeticSubarrays({-3,-6,-8,-4,-2,-8,-6,0,0,0,0},{1},{4});
for (auto&& i : r) {
std::cout << (i ? "true\n" : "false\n");
}
}

View File

@ -3,4 +3,4 @@ PROJECT(2303)
SET(CMAKE_CXX_STANDARD 23)
ADD_EXECUTABLE(2303 230322.cpp)
ADD_EXECUTABLE(2303 230323-CN.cpp)