Please help understanding: lazysegtree usage for range incremnents and range sums
ikr opened this issue · 2 comments
ikr commented
The following two tests fail for me:
#include "atcoder/lazysegtree.hpp"
#include "lest.hpp"
using namespace std;
constexpr int op(int x, int y) { return x + y; }
constexpr int e() { return 0; }
struct Calc final {
void increment_range_inclusive(const int a, const int b) {
lst.apply(a, b + 1, 1);
}
int sum_all() { return lst.all_prod(); }
Calc() : lst(1'000'000) {}
private:
atcoder::lazy_segtree<int, op, e, int, op, op, e> lst;
};
// clang-format off
const lest::test tests[] = {
CASE("Example 0") {
Calc c{};
c.increment_range_inclusive(1, 100);
c.increment_range_inclusive(301, 400);
c.increment_range_inclusive(101, 101);
c.increment_range_inclusive(101, 102);
c.increment_range_inclusive(1, 3);
EXPECT(206 == c.sum_all());
},
CASE("Example 1") {
Calc c{};
c.increment_range_inclusive(1, 1);
c.increment_range_inclusive(4, 4);
c.increment_range_inclusive(51, 53);
EXPECT(5 == c.sum_all());
},
};
// clang-format on
int main(int argc, char **argv) { return lest::run(tests, argc, argv); }
Like that:
./solution.cpp:31: failed: Example 0: 206 == c.sum_all() for 206 == 20
./solution.cpp:39: failed: Example 1: 5 == c.sum_all() for 5 == 4
2 out of 2 selected tests failed.
Obviously, I misunderstand how to use atcoder::lazy_segtree
for that kind of task. Could you please explain, what's the right way to increment ranges, and obtain the range sums then? Thank you!
Ah, btw, I did read the tutorial, and it even made sense :) but I'm still confused ¯\_(ツ)_/¯
TumoiYorozu commented
( Probably this is not the place to ask how to use it, but here is the code that works for your reference).
Reference: https://betrue12.hateblo.jp/entry/2020/09/23/005940#%E5%8C%BA%E9%96%93%E5%8A%A0%E7%AE%97%E5%8C%BA%E9%96%93%E5%92%8C%E5%8F%96%E5%BE%97
#include "atcoder/lazysegtree.hpp"
using namespace std;
constexpr int op(int x, int y) { return x + y; }
constexpr int e() { return 0; }
struct S{
int value;
int size;
};
S S_op(S a, S b){ return {a.value+b.value, a.size+b.size}; }
S S_e(){ return {0, 1}; }
S mapping(int f, S x){
return {x.value+x.size*f, x.size};
}
struct Calc final {
void increment_range_inclusive(const int a, const int b) {
lst.apply(a, b + 1, 1);
}
int sum_all() { return lst.all_prod().value; }
Calc() : lst(1'000'000) {}
private:
atcoder::lazy_segtree<S, S_op, S_e, int, mapping, op, e> lst;
};
// clang-format off
template<typename T>
void EXPECT(T excect, T res) {
cout << "excect:" << excect << ", res:" << res << (excect == res ? " OK" : " NG") << endl;
}
void test() {
{
Calc c{};
c.increment_range_inclusive(1, 100);
c.increment_range_inclusive(301, 400);
c.increment_range_inclusive(101, 101);
c.increment_range_inclusive(101, 102);
c.increment_range_inclusive(1, 3);
EXPECT(206, c.sum_all());
}
{
Calc c{};
c.increment_range_inclusive(1, 1);
c.increment_range_inclusive(4, 4);
c.increment_range_inclusive(51, 53);
EXPECT(5, c.sum_all());
}
};
// clang-format on
int main(int argc, char **argv) {
test();
}
ikr commented
@TumoiYorozu Awesome! Thanks a bunch!