Library

This documentation is automatically generated by competitive-verifier/competitive-verifier

View the Project on GitHub anmichi/Library

:x: test/CHT-Arbitary.test.cpp

Depends on

Code

// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/line_add_get_min
#include "../CHT-Arbitary.cpp"
using ll = long long;
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, q;
    cin >> n >> q;
    CHT_Arbitary<ll, true> cht;
    for (int i = 0; i < n; i++) {
        ll a, b;
        cin >> a >> b;
        cht.add(-a, -b);
    }
    while (q--) {
        int t;
        cin >> t;
        if (t == 0) {
            ll a, b;
            cin >> a >> b;
            cht.add(-a, -b);
        } else {
            ll p;
            cin >> p;
            cout << -cht.query(p) << "\n";
        }
    }
}
#line 1 "test/CHT-Arbitary.test.cpp"
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/line_add_get_min
#line 1 "CHT-Arbitary.cpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T, bool isMax = false>
struct CHT_Arbitary {
    static const T inf = numeric_limits<T>::max();
    struct Line {
        mutable T k, m, p;
        bool operator<(const Line &o) const {
            if (k == o.k) return (m > o.m) ^ isMax;
            return (k > o.k) ^ isMax;
        }
        bool operator<(T x) const { return p < x; }
    };
    multiset<Line, less<>> st;
    T div_floor(T a, T b) {
        if (is_integral_v<T>) return a / b - ((a ^ b) < 0 && a % b);
        return a / b;
    }
    bool intersect(multiset<Line, less<>>::iterator x, multiset<Line, less<>>::iterator y) {
        if (y == st.end()) return x->p = inf, 0;
        if (x->k == y->k)
            x->p = -inf;
        else
            x->p = div_floor(y->m - x->m, x->k - y->k);
        return x->p >= y->p;
    }
    void add(T k, T m) {
        auto z = st.insert({k, m, 0}), y = z++, x = y;
        while (intersect(y, z)) z = st.erase(z);
        if (x != st.begin() && intersect(--x, y)) intersect(x, y = st.erase(y));
        while ((y = x) != st.begin() && (--x)->p >= y->p) intersect(x, st.erase(y));
    }
    T query(T x) {
        assert(!st.empty());
        auto l = *st.lower_bound(x);
        return l.k * x + l.m;
    }
};
#line 3 "test/CHT-Arbitary.test.cpp"
using ll = long long;
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, q;
    cin >> n >> q;
    CHT_Arbitary<ll, true> cht;
    for (int i = 0; i < n; i++) {
        ll a, b;
        cin >> a >> b;
        cht.add(-a, -b);
    }
    while (q--) {
        int t;
        cin >> t;
        if (t == 0) {
            ll a, b;
            cin >> a >> b;
            cht.add(-a, -b);
        } else {
            ll p;
            cin >> p;
            cout << -cht.query(p) << "\n";
        }
    }
}

Test cases

Env Name Status Elapsed Memory
clang++ example_00 :heavy_check_mark: AC 6 ms 4 MB
clang++ half_00 :heavy_check_mark: AC 62 ms 4 MB
clang++ hand_max_00 :heavy_check_mark: AC 243 ms 16 MB
clang++ max_random_00 :heavy_check_mark: AC 101 ms 4 MB
clang++ max_random_01 :heavy_check_mark: AC 96 ms 4 MB
clang++ max_random_02 :heavy_check_mark: AC 95 ms 4 MB
clang++ no_output_00 :heavy_check_mark: AC 100 ms 3 MB
clang++ parabola_random_00 :heavy_check_mark: AC 190 ms 16 MB
clang++ parabola_random_01 :heavy_check_mark: AC 186 ms 16 MB
clang++ parabola_random_02 :heavy_check_mark: AC 192 ms 16 MB
clang++ random_00 :heavy_check_mark: AC 68 ms 4 MB
clang++ random_01 :heavy_check_mark: AC 73 ms 4 MB
clang++ random_02 :heavy_check_mark: AC 49 ms 4 MB
clang++ small_00 :heavy_check_mark: AC 9 ms 4 MB
clang++ small_01 :heavy_check_mark: AC 8 ms 4 MB
Back to top page