답안 #123828

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
123828 2019-07-02T07:35:33 Z FutymyClone Building Bridges (CEOI17_building) C++14
0 / 100
95 ms 2936 KB
#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
const long long inf = 1LL << 62;

int n, h[N], w[N];
long long dp[N], f[N];

class ConvexHullTrick {
    struct line {
        long long m, b, value;
        double xlo;
        bool is_query, query_max;

        line(long long m, long long b, long long v, bool is_query, bool query_max)
            : m(m), b(b), value(v), xlo(-std::numeric_limits<double>::max()),
            is_query(is_query), query_max(query_max) {}

        double intersect(const line &l) const {
            if (m == l.m) return std::numeric_limits<double>::max();
            return (double)(l.b - b)/(m - l.m);
        }

        bool operator<(const line &l) const {
            if (l.is_query) return query_max ? (xlo < l.value) : (l.value < xlo);
            return m < l.m;
        }
    };

    std::set<line> hull;
    bool query_max;

    typedef std::set<line>::iterator hulliter;

    bool has_prev(hulliter it) const {
        return it != hull.begin();
    }

    bool has_next(hulliter it) const {
        return (it != hull.end()) && (++it != hull.end());
    }

    bool irrelevant(hulliter it) const {
        if (!has_prev(it) || !has_next(it)) return false;
        hulliter prev = it, next = it;
        --prev;
        ++next;
        return query_max ? (prev->intersect(*next) <= prev->intersect(*it))
                        : (next->intersect(*prev) <= next->intersect(*it));
    }

    hulliter update_left_border(hulliter it) {
        if ((query_max && !has_prev(it)) || (!query_max && !has_next(it))) return it;
        hulliter it2 = it;
        double value = it->intersect(query_max ? *--it2 : *++it2);
        line l(*it);
        l.xlo = value;
        hull.erase(it++);
        return hull.insert(it, l);
    }

    public:
    ConvexHullTrick(bool query_max = false) : query_max(query_max) {}

    void add(long long m, long long b) {
        line l(m, b, 0, false, query_max);
        hulliter it = hull.lower_bound(l);
        if (it != hull.end() && it->m == l.m) {
            if ((query_max && it->b < b) || (!query_max && b < it->b)) hull.erase(it++);
            else return;
        }

        it = hull.insert(it, l);
        if (irrelevant(it)) {
            hull.erase(it);
            return;
        }

        while (has_prev(it) && irrelevant(--it)) hull.erase(it++);
        while (has_next(it) && irrelevant(++it)) hull.erase(it--);

        it = update_left_border(it);
        if (has_prev(it)) update_left_border(--it);
        if (has_next(++it)) update_left_border(++it);
    }

    long long query(long long x) const {
        line q(0, 0, x, true, query_max);
        hulliter it = hull.lower_bound(q);
        if (query_max) --it;
        return it->m*x + it->b;
    }
} slope;

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
    for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
    for (int i = 1; i <= n; i++) f[i] = f[i - 1] + w[i];

    //dp(i) = max(dp(j) + f(i - 1) - f(j) + hi^2 + hj^2 - 2hihj | j < i)
    //dp(i) = max(-2hjhi + hj^2 + dp(j) - f(j) + f(i - 1) + hi^2 | j < i)
    memset(dp, 0x3f, sizeof(dp));
    dp[1] = 0;
    slope.add(-2 * h[1], 1LL * h[1] * h[1] + dp[1] - f[1]);
    for (int i = 2; i <= n; i++) {
        dp[i] = slope.query(h[i]) + f[i - 1] + 1LL * h[i] * h[i];
        slope.add(-2 * h[i], 1LL * h[i] * h[i] + dp[i] - f[i]);
    }

    printf("%lld", dp[n]);
    return 0;
}
/*
6
3 8 7 1 6 6
0 -1 9 1 2 0
*/

Compilation message

building.cpp: In function 'int main()':
building.cpp:98:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
     ~~~~~^~~~~~~~~~
building.cpp:99:39: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
                                  ~~~~~^~~~~~~~~~~~~
building.cpp:100:39: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
                                  ~~~~~^~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 1144 KB Output is correct
2 Incorrect 2 ms 1144 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 95 ms 2936 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 1144 KB Output is correct
2 Incorrect 2 ms 1144 KB Output isn't correct
3 Halted 0 ms 0 KB -