Submission #669558

# Submission time Handle Problem Language Result Execution time Memory
669558 2022-12-06T18:23:09 Z four_specks Building Bridges (CEOI17_building) C++17
30 / 100
42 ms 4052 KB
#include <bits/stdc++.h>

using namespace std;

inline namespace
{
    template <typename T>
    T fl_div(T a, T b) { return a / b - ((a ^ b) < 0 && a % b); }

    template <typename T>
    struct Line
    {
        T m, c;
        T operator()(T x) const { return m * x + c; }
    };

    template <typename T>
    struct LineContainerObject
    {
        T m, c;
        mutable T p;

        bool operator<(const LineContainerObject &i_line) const { return m < i_line.m; }
        bool operator<(T x) const { return p < x; }
    };

    template <typename T>
    struct LineContainer : multiset<LineContainerObject<T>, less<>>
    {
        void add(const Line<T> &line)
        {
            auto it = Base::insert({line.m, line.c, 0});
            while (isect(it))
                Base::erase(next(it));
            if (it != Base::begin())
            {
                if (isect(--it))
                {
                    Base::erase(next(it));
                    isect(it);
                }
            }
            while (it != Base::begin() && isect(--it))
            {
                Base::erase(next(it));
            }
        }

        T query(T x)
        {
            auto it = Base::lower_bound(x);
            return it->m * x + it->c;
        }

    private:
        using Base = multiset<LineContainerObject<T>, less<>>;
        using Iterator = typename Base::iterator;

        inline static const T INF = numeric_limits<T>::max();

        bool isect(Iterator it)
        {
            if (next(it) == Base::end())
            {
                it->p = INF;
                return 0;
            }

            if (it->m == next(it)->m)
                it->p = it->c > next(it)->c ? INF : -INF;
            else
                it->p = fl_div(next(it)->c - it->c, it->m - next(it)->m);

            return it->p >= next(it)->p;
        }
    };

} // namespace

void solve()
{
    int n;
    cin >> n;

    vector<long> h(n), w(n);
    for (long &x : h)
        cin >> x;
    for (long &x : w)
        cin >> x;

    long add = 0;
    for (long x : w)
        add += x;

    vector<long> dp(n);
    LineContainer<long> cht;
    dp[0] = w[0];
    cht.add(Line<long>{2 * h[0], dp[0] - h[0] * h[0]});
    for (int i = 1; i < n; i++)
    {
        dp[i] = cht.query(h[i]) - h[i] * h[i] + w[i];
        cht.add(Line<long>{2 * h[i], dp[i] - h[i] * h[i]});
    }

    cout << -dp[n - 1] + add << '\n';
}

int main()
{
    ios_base::sync_with_stdio(false), cin.tie(NULL);

    solve();

    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Incorrect 0 ms 212 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 41 ms 2736 KB Output is correct
2 Correct 41 ms 2664 KB Output is correct
3 Correct 42 ms 2748 KB Output is correct
4 Correct 38 ms 2684 KB Output is correct
5 Correct 42 ms 4052 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Incorrect 0 ms 212 KB Output isn't correct
4 Halted 0 ms 0 KB -