답안 #819460

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
819460 2023-08-10T10:57:41 Z borisAngelov Building Bridges (CEOI17_building) C++17
100 / 100
76 ms 67176 KB
#include <bits/stdc++.h>

using namespace std;

const int maxn = 100005;
const int max_size = 1000000;
const long long inf = (1LL << 62);

int n;

long long h[maxn];
long long w[maxn];
long long pref[maxn];
long long dp[maxn];

struct line
{
    long long a;
    long long b;

    line()
    {
        a = 0;
        b = inf;
    }

    line(long long _a, long long _b)
    {
        a = _a;
        b = _b;
    }

    long long calc(long long x)
    {
        return a * x + b;
    }
};

struct li_chao_tree
{
    line tree[4 * max_size + 20];

    void update(int node, int l, int r, line new_line)
    {
        if (tree[node].calc(l) < new_line.calc(l) && tree[node].calc(r) < new_line.calc(r))
        {
            return;
        }

        int mid = (l + r) / 2;

        if (tree[node].calc(mid) > new_line.calc(mid))
        {
            swap(tree[node], new_line);
        }

        if (tree[node].calc(l) > new_line.calc(l))
        {
            update(2 * node, l, mid, new_line);
        }

        if (tree[node].calc(r) > new_line.calc(r))
        {
            update(2 * node + 1, mid + 1, r, new_line);
        }
    }

    long long query(int node, int l, int r, int pos)
    {
        if (l == r)
        {
            return tree[node].calc(pos);
        }

        int mid = (l + r) / 2;

        if (pos <= mid)
        {
            return min(tree[node].calc(pos), query(2 * node, l, mid, pos));
        }

        return min(tree[node].calc(pos), query(2 * node + 1, mid + 1, r, pos));
    }

    void update(const line& new_line)
    {
        update(1, 0, max_size, new_line);
    }

    long long query(int pos)
    {
        return query(1, 0, max_size, pos);
    }
};

li_chao_tree tree;

void fastIO()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

int main()
{
    fastIO();

    cin >> n;

    for (int i = 1; i <= n; ++i)
    {
        cin >> h[i];
    }

    for (int i = 1; i <= n; ++i)
    {
        cin >> w[i];
        pref[i] = pref[i - 1] + w[i];
    }

    dp[1] = 0;

    line curr = line(-(2 * h[1]), h[1] * h[1] - pref[1]);
    tree.update(curr);

    for (int i = 2; i <= n; ++i)
    {
        dp[i] = h[i] * h[i] + pref[i - 1] + tree.query(h[i]);

        curr = line(-(2 * h[i]), dp[i] + h[i] * h[i] - pref[i]);
        tree.update(curr);
    }

    cout << dp[n] << endl;

    return 0;
}

/*
6
3 8 7 1 6 6
0 -1 9 1 2 0
*/
# 결과 실행 시간 메모리 Grader output
1 Correct 31 ms 62932 KB Output is correct
2 Correct 26 ms 62920 KB Output is correct
3 Correct 30 ms 62848 KB Output is correct
4 Correct 26 ms 62896 KB Output is correct
5 Correct 29 ms 62976 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 61 ms 66456 KB Output is correct
2 Correct 64 ms 67036 KB Output is correct
3 Correct 66 ms 66980 KB Output is correct
4 Correct 61 ms 66944 KB Output is correct
5 Correct 76 ms 66956 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 31 ms 62932 KB Output is correct
2 Correct 26 ms 62920 KB Output is correct
3 Correct 30 ms 62848 KB Output is correct
4 Correct 26 ms 62896 KB Output is correct
5 Correct 29 ms 62976 KB Output is correct
6 Correct 61 ms 66456 KB Output is correct
7 Correct 64 ms 67036 KB Output is correct
8 Correct 66 ms 66980 KB Output is correct
9 Correct 61 ms 66944 KB Output is correct
10 Correct 76 ms 66956 KB Output is correct
11 Correct 63 ms 67176 KB Output is correct
12 Correct 67 ms 67040 KB Output is correct
13 Correct 76 ms 67084 KB Output is correct
14 Correct 75 ms 67160 KB Output is correct
15 Correct 58 ms 66820 KB Output is correct
16 Correct 55 ms 66940 KB Output is correct
17 Correct 44 ms 67096 KB Output is correct
18 Correct 46 ms 67040 KB Output is correct