Skip to content

Commit

Permalink
fix: upload
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiphereth-A committed Feb 27, 2024
1 parent 0984bbb commit 26c4e95
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 27 deletions.
31 changes: 19 additions & 12 deletions src/code/util/blocking.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,47 @@

namespace tifa_libs {

template <class T>
template <class T, class Tag_t = T>
class blocking {
const u32 bsz;
vec<T> dt, bs;
vec<Tag_t> tag;

constexpr auto block_l(u32 id) { return dt.begin() + std::min((u32)dt.size(), id * bsz); }
constexpr u32 block_id(u32 idx) const { return idx / bsz; }

public:
// @param block_func init function for block: block_func(block, data.begin() + xl, data.begin() + xr); change value of block with range [xl, xr)
// @param block_func init function for block: block_func(block, tag, block_id, data.begin() + xl, data.begin() + xr); change value of block with range [xl, xr)
template <class FB>
requires requires(FB f) {
f(bs[0], dt.begin(), dt.end());
f(bs[0], tag[0], 0_u32, dt.begin(), dt.end());
}
constexpr blocking(u32 block_size, vec<T> const& data, FB&& block_func) : bsz(block_size), dt(data), bs((data.size() + block_size - 1) / block_size) {
constexpr blocking(u32 block_size, vec<T> const& data, FB&& block_func) : bsz(block_size), dt(data), bs((data.size() + block_size - 1) / block_size), tag(bs.size()) {
assert(block_size && block_size <= data.size());
for (u32 i = 0; i < bs.size(); ++i) block_func(bs[i], block_l(i), block_l(i + 1));
for (u32 i = 0; i < bs.size(); ++i) block_func(bs[i], tag[i], i, block_l(i), block_l(i + 1));
}
constexpr vec<T> const& data() const { return dt; }
constexpr vec<T> const& block_data() const { return bs; }

// @param f update function for block: f(block, tag, block_id, data.begin() + xl, data.begin() + xr); change value of block with range [xl, xr)
template <class F>
requires requires(F f) { f(bs[0], tag[0], 0_u32, dt.begin(), dt.end()); }
constexpr void update_block(u32 id, F&& f) { f(bs[id], tag[id], id, block_l(id), block_l(id + 1)); }

//! range: [l, r)
// @param upd update function for single element: upd(block, data.begin() + xl, data.begin() + xr); update data in [xl, xr), change value of block
// @param updb update function for block: updb(block, data.begin() + xl, data.begin() + xr); change value of block with range [xl, xr)
// @param upd update function for single element: upd(block, tag, block_id, data.begin() + xl, data.begin() + xr); update data in [xl, xr), change value of block
// @param updb update function for block: updb(block, tag, block_id, data.begin() + xl, data.begin() + xr); change value of block with range [xl, xr)
template <class FD, class FDB>
requires requires(FD upd, FDB updb) {
upd(bs[0], dt.begin(), dt.end());
updb(bs[0], dt.begin(), dt.end());
upd(bs[0], tag[0], 0_u32, dt.begin(), dt.end());
updb(bs[0], tag[0], 0_u32, dt.begin(), dt.end());
}
constexpr void run(u32 l, u32 r, FD&& upd, FDB&& updb) {
assert(l < r);
u32 bl = block_id(l), br = block_id(r - 1);
for (u32 i = bl; i <= br; ++i) updb(bs[i], block_l(i), block_l(i + 1));
if (auto L = dt.begin() + l, R = block_l(bl); L < R) upd(bs[bl - 1], L, R);
if (auto L = block_l(br + 1), R = dt.begin() + r; L < R) upd(bs[br + 1], L, R);
for (u32 i = bl; i <= br; ++i) update_block(i, std::forward<FDB>(updb));
if (auto L = dt.begin() + l, R = block_l(bl); L < R) upd(bs[bl - 1], tag[bl - 1], bl - 1, L, R);
if (auto L = block_l(br + 1), R = dt.begin() + r; L < R) upd(bs[br + 1], tag[br + 1], br + 1, L, R);
}
};

Expand Down
24 changes: 17 additions & 7 deletions src/test_cpverifier/aizu/dsl_2_a.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,35 @@ int main() {
std::cin.tie(nullptr);
u32 n, q;
std::cin >> n >> q;
tifa_libs::blocking<u32> blk(std::max(1_u32, tifa_libs::math::isqrt(n)), vec<u32>(n, INT32_MAX), [](u32& b, auto, auto) { b = INT32_MAX; });
tifa_libs::blocking<u32> blk(std::max(1_u32, tifa_libs::math::isqrt(n)), vec<u32>(n, INT32_MAX), [](u32& b, u32, u32, auto, auto) { b = INT32_MAX; });
auto f = [](u32& b, u32& tag, u32, auto l, auto r) {
std::fill(l, r, b);
tag = 0;
};
for (u32 i = 0, op, x, y, res; i < q; ++i) {
std::cin >> op >> x >> y;
if (op) {
res = INT32_MAX;
blk.run(
x, y + 1,
[&](u32, auto l, auto r) { res = std::min(res, *std::min_element(l, r)); },
[&](u32 b, auto, auto) { res = std::min(res, b); });
[&](u32 b, u32& tag, u32 bid, auto l, auto r) {
if (tag) {
blk.update_block(bid, f);
res = b;
} else res = std::min(res, *std::min_element(l, r));
},
[&](u32 b, u32&, u32, auto, auto) { res = std::min(res, b); });
std::cout << res << '\n';
} else blk.run(
x, x + 1,
[&](u32& b, auto l, auto r) {
[&](u32& b, u32& tag, u32 bid, auto l, auto r) {
if (tag) blk.update_block(bid, f);
b = std::min(b, y);
for (auto i = l; i != r; ++i) *i = y;
std::fill(l, r, y);
},
[&](u32& b, auto l, auto r) {
[&](u32& b, u32& tag, u32, auto, auto) {
b = y;
for (auto i = l; i != r; ++i) *i = y;
tag = 1;
});
}
return 0;
Expand Down
22 changes: 14 additions & 8 deletions src/test_cpverifier/aizu/dsl_2_b.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,32 @@ int main() {
std::cin.tie(nullptr);
u32 n, q;
std::cin >> n >> q;
tifa_libs::blocking<u32> blk(std::max(1_u32, tifa_libs::math::isqrt(n)), vec<u32>(n), [](u32& b, auto, auto) { b = 0; });
tifa_libs::blocking<u32> blk(std::max(1_u32, tifa_libs::math::isqrt(n)), vec<u32>(n), [](u32& b, u32, u32, auto, auto) { b = 0; });
auto f = [](u32& b, u32& tag, u32, auto l, auto r) {
b += tag * (r - l);
for (auto i = l; i != r; ++i) *i += tag;
tag = 0;
};
for (u32 i = 0, op, x, y, res; i < q; ++i) {
std::cin >> op >> x >> y;
if (op) {
res = 0;
blk.run(
x, y + 1,
[&](u32, auto l, auto r) { res += std::reduce(l, r); },
[&](u32 b, auto l, auto r) { res += b * (r - l); });
[&](u32, u32 tag, u32 id, auto l, auto r) {
if (tag) blk.update_block(id, f);
res += std::reduce(l, r);
},
[&](u32 b, u32 tag, u32, auto l, auto r) { res += b + tag * (r - l); });
std::cout << res << '\n';
} else blk.run(
x, x + 1,
[&](u32& b, auto l, auto r) {
[&](u32& b, u32& tag, u32 id, auto l, auto r) {
if (tag) blk.update_block(id, f);
b += y * (r - l);
for (auto i = l; i != r; ++i) *i += y;
},
[&](u32& b, auto l, auto r) {
b += y * (r - l);
for (auto i = l; i != r; ++i) *i += y;
});
[&](u32&, u32& tag, u32, auto, auto) { tag += y; });
}
return 0;
}

0 comments on commit 26c4e95

Please sign in to comment.