Issue with `lazysegtree`
guoyiz23 opened this issue · 1 comments
#include <atcoder/lazysegtree>
using namespace std;
using namespace atcoder;
using lint = long long;
lint op(lint a,lint b){return a+b;}
lint e(){return 0;}
lint mapping(lint f, lint x) { return x+f; }
lint composition(lint f, lint g) { return f+g; }
lint id() { return 0; }
int main() {
#define si(x) int(x.size())
vector<lint> a{2,5,5};
lazy_segtree<lint, op, e, lint, mapping, composition, id> seg(a);
auto res{0ll};
for (int i=0; i<si(a); i++) {
seg.apply(0,si(a),-a[i]);
auto lower{seg.prod(0,i)}, higher{seg.prod(i+1,si(a))};
printf("lower = %lld, higher = %lld\n", lower, higher);
assert(lower <= 0);
assert(higher >= 0);
res -= lower;
res += higher;
seg.apply(0,si(a),a[i]);
}
return 0;
}
The above code prints
lower = 0, higher = 6
lower = -3, higher = 0
lower = 2, higher = 0
and fails the assert
. This code is meant to compute the sum of absolute value of differences between all pairs of elements in a sorted array.
When I remove the if
condition in https://github.com/atcoder/ac-library/blob/master/atcoder/lazysegtree.hpp#L135 as well as the one on L136
, the code works on this case. I won't go into full detail for now, but basically, there is a node the value of which needs to be updated (to be equal to the sum of those of its two children), and that if
condition is getting in the way.
I was led to this by https://atcoder.jp/contests/abc351/tasks/abc351_e.
Moreover, even after I removed that aforementioned if
, the value of res
at the end for a = {3, 3, 4}
is 2
when it should be 4
.
I actually examined the case of a = {2, 5, 5}
closely (ran thru with many debug print statements) but have yet to look into that of a = {3, 3, 4}
, would be happy to discuss. Feel free to contact me via email at guoyiz at yandex.ru
. Thank you!
Per yosupo06/library-checker-problems#1137 (comment) looks like I had used it wrong. Sorry about that. Surely, it was very difficult for me to believe that there could actually be something wrong with such a commonly used library.