From 14e85b0162fd289fb7453e9a0d541a261e3546e8 Mon Sep 17 00:00:00 2001 From: MZuenni Date: Tue, 17 Oct 2023 14:43:15 +0200 Subject: changed lichao --- datastructures/lichao.cpp | 57 +++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/datastructures/lichao.cpp b/datastructures/lichao.cpp index 69ee47f..e12d243 100644 --- a/datastructures/lichao.cpp +++ b/datastructures/lichao.cpp @@ -1,49 +1,44 @@ vector xs; // IMPORTANT: Initialize before constructing Lichao! +int findX(int i) {return distance(xs.begin(), lower_bound(all(xs), i));} struct Fun{ // Default: Linear function. Change it to needed function type. ll m, c; - ll operator()(int x){ - return m*xs[x] + c; - } + ll operator()(int x) {return m*xs[x] + c;} }; // Default: Computes min. Change lines with comment for max. struct Lichao{ - const Fun id = {0, inf}; // {0, -inf} + static constexpr Fun id = {0, inf}; // {0, -inf} int n, cap; vector seg; - Lichao(){ - n = sz(xs); - for(cap = 1; cap < n; cap *= 2); - seg.assign(2*cap, id); - } - void myInsert(Fun f, int l, int r, int i){ - while(i < 2*cap){ + Lichao() : n(sz(xs)), cap(2<<__lg(n)), seg(2*cap, id) {} + + void _insert(Fun f, int l, int r, int i) { + while (i < 2*cap){ int m = (l+r)/2; - if(m >= n) {r = m; i = 2*i; continue;} + if (m >= n) {r = m; i = 2*i; continue;} Fun &g = seg[i]; - if(f(m) < g(m)) swap(f, g); // > - if(f(l) < g(l)) r = m, i = 2*i; // > + if (f(m) < g(m)) swap(f, g); // > + if (f(l) < g(l)) r = m, i = 2*i; // > else l = m, i = 2*i+1; - } - } - void mySegmentInsert(Fun f, int l, int r, int a, int b, int i){ - if(l <= a && b <= r) myInsert(f, a, b, i); - else if(a < r && l < b){ + }} + void insert(Fun f) {_insert(f, 0, cap, 1);} + + void _segmentInsert(Fun f, int l, int r, int a, int b, int i) { + if (l <= a && b <= r) _insert(f, a, b, i); + else if (a < r && l < b){ int m = (a+b)/2; - mySegmentInsert(f, l, r, a, m, 2*i); - mySegmentInsert(f, l, r, m, b, 2*i+1); - } - } - void insert(Fun f){myInsert(f, 0, cap, 1);} - void segmentInsert(Fun f, ll l, ll r){ - mySegmentInsert(f, lower_bound(all(xs), l)-xs.begin(), lower_bound(all(xs), r)-xs.begin(), 0, cap, 1); + _segmentInsert(f, l, r, a, m, 2*i); + _segmentInsert(f, l, r, m, b, 2*i+1); + }} + void segmentInsert(Fun f, ll l, ll r) { + _segmentInsert(f, findX(l), findX(r), 0, cap, 1); } - ll myQuery(int x){ - int i = x+cap; - ll ans = seg[i](x); - while(i > 1) ans = min(ans, seg[i/=2](x)); // max + + ll _query(int x) { + ll ans = inf; // -inf + for (int i = x + cap; i > 0; i /= 2) ans = min(ans, seg[i](x)); // max return ans; } - ll query(ll x){return myQuery(lower_bound(all(xs),x)-xs.begin());} + ll query(ll x) {return _query(findX(x));} }; -- cgit v1.2.3