Submission #1359797

#TimeUsernameProblemLanguageResultExecution timeMemory
1359797AzeTurk810Building Bridges (CEOI17_building)C++20
60 / 100
3092 ms8308 KiB
/*
Telebe of Adicto && Mamedov yani AzeTurk810
I see humans but no humanity
*/
#include <algorithm>
#include <deque>
#include <iostream>
#include <utility>
#include <vector>

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

using ll = long long;
using db = long double;
using i128 = __int128_t;
using namespace std;

#define ln '\n'
#define INFi 1e9
#define INFll 1e18

#ifdef ONPC
#include <algo.hpp>
#else
#define dbg(...)
#define dbg_out(...)
#endif

size_t _n;
vector<ll> W, H;
struct CHT {
    struct line {
        int k, b;
        line(int k, int b) : k(k), b(b) {}
        int f(int x) {
            return x * k + b;
        }
        db col2(line a) { // NOTE: intersection point(x) of 2 lines
            return db(a.b - b) / db(k - a.k);
        }
        int col(line a) {
            return (a.b - b + k - a.k - 1) / k - a.k;
        }
    };
    deque<pair<line, int>> dq;
    void insert(int k, int b) {
        line l(k, b);
        while (dq.size() > 1 && dq.back().second >= dq.back().first.col(l)) {
            dq.pop_back();
        }
        if (dq.empty()) {
            dq.emplace_back(l, 0);
            return;
        }
        dq.emplace_back(l, dq.back().first.col(l));
    }

    int query(int x) {
        while (dq.size() > 1) {
            if (dq[1].second <= x) {
                dq.pop_back();
            } else {
                break;
            }
        }
        return dq.front().first.f(x);
    }
};

struct LiChaoTree {
    struct Line {
        ll k, c;
        Line(ll k = 0, ll c = INFll) : k(k), c(c) {}
        ll get(ll x) {
            i128 prod = (i128)k * x + c;
            if (prod > INFll)
                return INFll;
            if (prod < -INFll)
                return -INFll;
            return k * x + c;
        }
    };

    struct Node {
        Line L;
        pair<int, int> interval;
        Node *l, *r;
        Node(Line V, ll l, ll r) : L(V), interval(make_pair(l, r)), l(nullptr), r(nullptr) {}
    };
    ll _L, _R;
    Node *root;
    LiChaoTree(ll l = -INFi, ll r = INFi) {
        _L = l, _R = r;
        root = new Node(Line(), l, r);
    }
    ll ask(Node *v, ll x) {
        if (v == nullptr)
            return INFll;
        auto [l, r] = v->interval;
        if (l == r)
            return v->L.get(x);
        ll mid = (l + r) >> 1LL;
        if (x <= mid) {
            return min(ask(v->l, x), v->L.get(x));
        } else {
            return min(ask(v->r, x), v->L.get(x));
        }
    }

    Node *add(Node *v, Line L, ll _l, ll _r) {
        if (v == nullptr) {
            return new Node(L, _l, _r);
        }
        auto [l, r] = v->interval;
        ll mid = (l + r) >> 1LL;
        if (L.get(mid) < v->L.get(mid)) {
            swap(v->L, L);
        }
        if (L.get(l) > v->L.get(l) && L.get(r) > v->L.get(r))
            return v;
        if (L.get(l) < v->L.get(l)) {
            v->l = add(v->l, L, _l, mid);
        } else {
            v->r = add(v->r, L, mid + 1, _r);
        }
        return v; 
    }

    ll query(ll x) {
        return ask(root, x);
    }
    void add(ll k, ll b) {
        root = add(root, Line(k, b), _L, _R);
    }
};

vector<ll> pref, dp;

inline void systemd() {
    H.resize(_n + 1);
    W.resize(_n + 1);
    pref.resize(_n + 1);
    dp.resize(_n + 1);
}

char solve() {
    if (!(cin >> _n))
        return 1;
    systemd();
    for (size_t i = 1; i <= _n; i++) {
        cin >> H[i];
    }
    for (size_t i = 1; i <= _n; i++) {
        cin >> W[i];
    }
    for (size_t i = 1; i <= _n; i++) {
        pref[i] = pref[i - 1] + W[i];
    }
    LiChaoTree t(-1e6 - 1, 1e6 + 1);
    t.add(-2 * H[1], (ll)H[1] * H[1] - pref[1]);
    
    for (size_t i = 2; i <= _n; i++) {
        ll best = t.query(H[i]);
        dp[i] = (ll)pref[i - 1] + best + (ll)H[i] * H[i];
        t.add(-2LL * H[i], (ll)dp[i] + (ll)H[i] * H[i] - pref[i]);
    }
    cout << dp.back() << ln;
    return 0;
}

// Attack on titan<3

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    int t = 1e9;
    // cin >> t;
    for (int cases = 0; cases < t; cases++) {
        if (solve())
            break;
#ifdef ONPC
        cerr << "__________\n";
#endif
    }
}
// Just Imaginary
/*
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠀⠀⠀⢀⣴⣾⠀⠀⠀⡀⢀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣦⣾⣿⣿⣿⣿⣿⡆⠁⠀⢀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⡠⠂⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠠⠔⠚⣿⣿⣿⣿⣿⣦⡄⠀⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢀⠠⠐⢂⠉⡀⣀⣤⣄⢻⣿⣿⡟⢈⡹⣿⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⡀⠄⠂⠈⠀⣶⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠘⣷⡀⠀⡀⠐⠂⠐⢄
⠀⠀⠀⠀⠀⠀⠀⣿⣿⠟⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣀⣾⣷⠯⠀⠤⠤⠄⠈
⠀⠀⠀⠀⠀⠀⣼⣿⡟⠀⠀⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣰⣿⠋⠀⠀⢠⣾⣿⣿⣿⣿⣿⣭⠟⢻⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀
⠀⠀⠀⣀⣶⡟⠁⠀⢾⣶⣿⠟⠉⠈⢻⣿⣿⣿⣦⣜⠀⠛⠛⠿⠁⠀⠀⠀⠀⠀
⠚⠻⠿⠿⡿⠁⠀⢠⣿⣿⠁⠀⣠⠖⠋⠉⠻⣿⣿⣿⣶⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣰⣿⡿⠃⠠⠊⠁⠀⠀⠀⠀⠈⢿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⣴⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⣠⣾⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢀⣴⠾⠟⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
*/
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...