답안 #477398

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
477398 2021-10-02T02:24:59 Z Tien_Noob Building Bridges (CEOI17_building) C++17
100 / 100
134 ms 5712 KB
#define task "BUILDING"

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

using ll = long long;
using ld = long double;

constexpr int N = 1e5 + 5;
constexpr ll Inf = 1e17;

#define sz(x) (int)(x.size())

int n;
ll h[N], w[N], dp[N];

ll A(int x)
{
    return -2 * h[x];
}

ll B(int x)
{
    return dp[x] - w[x] + h[x] * h[x];
}

ll More(int x)
{
    return h[x] * h[x] + w[x - 1];
}

ld inter(int x, int y)
{
    return (ld)1.0 * (B(x) - B(y)) / (A(y) - A(x));
}

struct ConvexHullTrick
{
    vector<int> line;
    vector<ld> point;
    bool Empty;

    ConvexHullTrick()
    {
        Empty = 1;
        point.emplace_back(-Inf);
    }

    void Clear()
    {
        Empty = 1;
        line.clear();
        point.clear();
        point.emplace_back(-Inf);
    }

    void Add(int i)
    {
        while (sz(line) >= 2 || (sz(line) == 1 && A(line[0]) == A(i)))
        {
            if (A(line.back()) != A(i))
            {
                if (inter(i, line.back()) <= inter(i, line[sz(line) - 2]))
                {
                    line.pop_back();
                    point.pop_back();
                }
                else
                    break;
            }
            else
            {
                if (B(line.back()) > B(i))
                {
                    line.pop_back();
                    if (!line.empty())
                        point.pop_back();
                }
                else
                    break;
            }
        }

        Empty = 0;

        if (line.empty() || A(line.back()) != A(i))
        {
            if (!line.empty())
                point.emplace_back(inter(i, line.back()));
            line.emplace_back(i);
        }
    }

    ll Get(int x)
    {
        if (Empty)
            return Inf;
        int j = lower_bound(point.begin(), point.end(), h[x]) - point.begin();
        //cout << line.back() << " " << j - 1 << " " << line[j - 1] << "\n";
        return A(line[j - 1]) * h[x] + B(line[j - 1]) + More(x);
    }
} f[17];

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

void Update(int x)
{
    int pos = 0;
    vector<int> tmp({x});

    while (pos < 17 && !f[pos].Empty)
    {
        for (auto i : f[pos].line)
            tmp.emplace_back(i);
        f[pos].Clear();
        ++pos;
    }

    sort(tmp.begin(), tmp.end(), [&](const int &x, const int &y)
         { return A(x) > A(y); });

    for (auto i : tmp)
        f[pos].Add(i);
}

void Solve()
{
    Update(1);

    for (int i = 2; i <= n; ++i)
    {
        dp[i] = Inf;
        for (int j = 0; j < 17; ++j)
            if (!f[j].Empty)
            {
                //cout << j << " ";
                dp[i] = min(dp[i], f[j].Get(i));
            }
        Update(i);
        //cout << i << ": " << dp[i] << "\n";
    }

    cout << dp[n];
}

int32_t main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    if (fopen(task ".INP", "r"))
    {
        freopen(task ".INP", "r", stdin);
        freopen(task ".OUT", "w", stdout);
    }
    Read();
    Solve();
}

Compilation message

building.cpp: In function 'int32_t main()':
building.cpp:167:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  167 |         freopen(task ".INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
building.cpp:168:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  168 |         freopen(task ".OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 332 KB Output is correct
2 Correct 0 ms 332 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 123 ms 2900 KB Output is correct
2 Correct 134 ms 2956 KB Output is correct
3 Correct 129 ms 2912 KB Output is correct
4 Correct 117 ms 2796 KB Output is correct
5 Correct 77 ms 3484 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 332 KB Output is correct
2 Correct 0 ms 332 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
6 Correct 123 ms 2900 KB Output is correct
7 Correct 134 ms 2956 KB Output is correct
8 Correct 129 ms 2912 KB Output is correct
9 Correct 117 ms 2796 KB Output is correct
10 Correct 77 ms 3484 KB Output is correct
11 Correct 110 ms 2736 KB Output is correct
12 Correct 127 ms 2848 KB Output is correct
13 Correct 63 ms 2748 KB Output is correct
14 Correct 124 ms 2812 KB Output is correct
15 Correct 95 ms 5712 KB Output is correct
16 Correct 69 ms 3536 KB Output is correct
17 Correct 33 ms 2632 KB Output is correct
18 Correct 34 ms 2612 KB Output is correct