提出 #24563891
ソースコード 拡げる
#line 1 "runtime/include/jikka/base.hpp"
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <functional>
#include <iostream>
#include <numeric>
#include <unordered_map>
#include <vector>
namespace jikka {
inline int64_t floordiv(int64_t n, int64_t d) {
assert(d != 0);
return n / d - ((n ^ d) < 0 && n % d);
}
inline int64_t floormod(int64_t n, int64_t d) {
assert(d != 0);
n %= d;
return (n < 0 ? n + d : n);
}
inline int64_t ceildiv(int64_t n, int64_t d) {
assert(d != 0);
return n / d + ((n ^ d) >= 0 && n % d);
}
inline int64_t ceilmod(int64_t n, int64_t d) {
assert(d != 0);
return n - ceildiv(n, d) * d;
}
inline int64_t pow(int64_t x, int64_t k) {
assert(k >= 0);
int64_t y = 1;
for (; k > 0; k >>= 1) {
if (k & 1) {
y *= x;
}
x *= x;
}
return y;
}
template <typename T, size_t H, size_t W>
using matrix = std::array<std::array<T, W>, H>;
template <size_t H, size_t W>
std::array<int64_t, H> matap(const matrix<int64_t, H, W> &a,
const std::array<int64_t, W> &b) {
std::array<int64_t, H> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y] += a[y][x] * b[x];
}
}
return c;
}
template <size_t N> matrix<int64_t, N, N> matzero() { return {}; }
template <size_t N> matrix<int64_t, N, N> matone() {
matrix<int64_t, N, N> a = {};
for (size_t i = 0; i < N; ++i) {
a[i][i] = 1;
}
return a;
}
template <size_t H, size_t W>
matrix<int64_t, H, W> matadd(const matrix<int64_t, H, W> &a,
const matrix<int64_t, H, W> &b) {
matrix<int64_t, H, W> c;
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y][x] = a[y][x] + b[y][x];
}
}
return c;
}
template <size_t H, size_t N, size_t W>
matrix<int64_t, H, W> matmul(const matrix<int64_t, H, N> &a,
const matrix<int64_t, N, W> &b) {
matrix<int64_t, H, W> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t z = 0; z < N; ++z) {
for (size_t x = 0; x < W; ++x) {
c[y][x] += a[y][z] * b[z][x];
}
}
}
return c;
}
template <size_t N>
matrix<int64_t, N, N> matpow(matrix<int64_t, N, N> x, int64_t k) {
matrix<int64_t, N, N> y = matone<N>();
for (; k; k >>= 1) {
if (k & 1) {
y = matmul(y, x);
}
x = matmul(x, x);
}
return y;
}
inline int64_t modnegate(int64_t a, int64_t MOD) { return floormod(-a, MOD); }
inline int64_t modplus(int64_t a, int64_t b, int64_t MOD) {
return floormod(a + b, MOD);
}
inline int64_t modminus(int64_t a, int64_t b, int64_t MOD) {
return floormod(a - b, MOD);
}
inline int64_t modmult(int64_t a, int64_t b, int64_t MOD) {
return floormod(a * b, MOD);
}
inline int64_t modinv(int64_t value, int64_t MOD) {
assert(0 < value and value < MOD);
int64_t a = value, b = MOD;
int64_t x = 0, y = 1;
for (int64_t u = 1, v = 0; a;) {
int64_t q = b / a;
x -= q * u;
std::swap(x, u);
y -= q * v;
std::swap(y, v);
b -= q * a;
std::swap(b, a);
}
assert(value * x + MOD * y == b and b == 1);
if (x < 0) {
x += MOD;
}
assert(0 <= x and x < MOD);
return x;
}
inline int64_t modpow(int64_t x, int64_t k, int64_t MOD) {
assert(k >= 0);
int64_t y = 1;
for (; k > 0; k >>= 1) {
if (k & 1) {
y = y * x % MOD;
}
x = x * x % MOD;
}
if (y < 0) {
y += MOD;
}
return y;
}
template <size_t H, size_t W>
std::array<int64_t, H> modmatap(const matrix<int64_t, H, W> &a,
const std::array<int64_t, W> &b, int64_t MOD) {
std::array<int64_t, H> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y] += a[y][x] * b[x] % MOD;
}
c[y] = floormod(c[y], MOD);
}
return c;
}
template <size_t H, size_t W>
matrix<int64_t, H, W> modmatadd(const matrix<int64_t, H, W> &a,
const matrix<int64_t, H, W> &b, int64_t MOD) {
matrix<int64_t, H, W> c;
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y][x] = floormod(a[y][x] + b[y][x], MOD);
}
}
return c;
}
template <size_t H, size_t N, size_t W>
matrix<int64_t, H, W> modmatmul(const matrix<int64_t, H, N> &a,
const matrix<int64_t, N, W> &b, int64_t MOD) {
matrix<int64_t, H, W> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t z = 0; z < N; ++z) {
for (size_t x = 0; x < W; ++x) {
c[y][x] += a[y][z] * b[z][x] % MOD;
}
}
}
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y][x] = floormod(c[y][x], MOD);
}
}
return c;
}
template <size_t N>
matrix<int64_t, N, N> modmatpow(matrix<int64_t, N, N> x, int64_t k,
int64_t MOD) {
matrix<int64_t, N, N> y = matone<N>();
for (; k; k >>= 1) {
if (k & 1) {
y = modmatmul(y, x, MOD);
}
x = modmatmul(x, x, MOD);
}
return y;
}
inline std::vector<int64_t> range(int64_t n) {
if (n < 0) {
return std::vector<int64_t>();
}
std::vector<int64_t> xs(n);
std::iota(xs.begin(), xs.end(), 0);
return xs;
}
inline int64_t fact(int64_t n) {
assert(0 <= n);
int64_t ans = 1;
for (int i = 0; i < n; ++i) {
ans *= i + 1;
}
return ans;
}
inline int64_t choose(int64_t n, int64_t r) {
assert(0 <= r and r <= n);
int64_t ans = 1;
for (int i = 0; i < r; ++i) {
ans *= n - i;
ans /= i + 1;
}
return ans;
}
inline int64_t permute(int64_t n, int64_t r) {
assert(0 <= r and r <= n);
int64_t ans = 1;
for (int i = 0; i < r; ++i) {
ans *= n - i;
}
return ans;
}
inline int64_t multichoose(int64_t n, int64_t r) {
assert(0 <= r and r <= n);
if (n == 0 and r == 0) {
return 1;
}
return choose(n + r - 1, r);
}
inline int64_t modfact(int64_t n, int64_t MOD) {
assert(0 <= n);
assert(1 <= MOD);
static std::unordered_map<int64_t, std::vector<int64_t>> memos;
auto &memo = memos[MOD];
while (static_cast<int64_t>(memo.size()) <= n) {
if (memo.empty()) {
memo.push_back(1);
}
memo.push_back(memo.size() * memo.back() % MOD);
}
return memo[n];
}
inline int64_t modchoose(int64_t n, int64_t r, int64_t MOD) {
assert(0 <= r and r <= n);
assert(1 <= MOD);
return modfact(n, MOD) * modinv(modfact(r, MOD), MOD) % MOD;
}
inline int64_t modpermute(int64_t n, int64_t r, int64_t MOD) {
assert(0 <= r and r <= n);
assert(1 <= MOD);
return modfact(n, MOD) *
modinv(modfact(n - r, MOD) * modfact(r, MOD) % MOD, MOD) % MOD;
}
inline int64_t modmultichoose(int64_t n, int64_t r, int64_t MOD) {
assert(0 <= r and r <= n);
assert(1 <= MOD);
if (n == 0 and r == 0) {
return 1;
}
return modchoose(n + r - 1, r, MOD);
}
template <class T> inline T error(const std::string &message) {
std::cerr << message << std::endl;
assert(false);
}
} // namespace jikka
#line 1 "runtime/include/jikka/convex_hull_trick.hpp"
#line 4 "runtime/include/jikka/convex_hull_trick.hpp"
#include <climits>
#line 6 "runtime/include/jikka/convex_hull_trick.hpp"
#include <map>
#include <set>
#include <utility>
namespace jikka {
namespace details {
/**
* @note y = ax + b
*/
struct line_t {
int64_t a, b;
};
bool operator<(line_t lhs, line_t rhs) {
return std::make_pair(-lhs.a, lhs.b) < std::make_pair(-rhs.a, rhs.b);
}
struct rational_t {
int64_t num, den;
};
bool operator<(rational_t lhs, rational_t rhs) {
if (lhs.num == INT64_MAX or rhs.num == -INT64_MAX)
return false;
if (lhs.num == -INT64_MAX or rhs.num == INT64_MAX)
return true;
return (__int128_t)lhs.num * rhs.den < (__int128_t)rhs.num * lhs.den;
}
} // namespace details
/*
* @brief Convex Hull Trick (非単調, online)
* @docs data_structure/convex_hull_trick.md
*/
class convex_hull_trick {
typedef details::line_t line_t;
typedef details::rational_t rational_t;
static rational_t make_rational(int64_t num, int64_t den = 1) {
if (den < 0) {
num *= -1;
den *= -1;
}
return {num, den}; // NOTE: no reduction
}
public:
convex_hull_trick() {
lines.insert({+INT64_MAX, 0}); // sentinels
lines.insert({-INT64_MAX, 0});
cross.emplace(make_rational(-INT64_MAX), (line_t){-INT64_MAX, 0});
}
/**
* @note O(log n)
*/
void add_line(int64_t a, int64_t b) {
auto it = lines.insert({a, b}).first;
if (not is_required(*prev(it), {a, b}, *next(it))) {
lines.erase(it);
return;
}
cross.erase(cross_point(*prev(it), *next(it)));
{ // remove right lines
auto ju = prev(it);
while (ju != lines.begin() and not is_required(*prev(ju), *ju, {a, b}))
--ju;
cross_erase(ju, prev(it));
it = lines.erase(++ju, it);
}
{ // remove left lines
auto ju = next(it);
while (next(ju) != lines.end() and
not is_required({a, b}, *ju, *next(ju)))
++ju;
cross_erase(++it, ju);
it = prev(lines.erase(it, ju));
}
cross.emplace(cross_point(*prev(it), *it), *it);
cross.emplace(cross_point(*it, *next(it)), *next(it));
assert(not empty());
}
bool empty() const { return lines.size() <= 2; }
/**
* @note O(log n)
*/
int64_t get_min(int64_t x) const {
assert(not empty());
line_t f = prev(cross.lower_bound(make_rational(x)))->second;
return f.a * x + f.b;
}
private:
std::set<line_t> lines;
std::map<rational_t, line_t> cross;
template <typename Iterator> void cross_erase(Iterator first, Iterator last) {
for (; first != last; ++first) {
cross.erase(cross_point(*first, *next(first)));
}
}
rational_t cross_point(line_t f1, line_t f2) const {
if (f1.a == INT64_MAX)
return make_rational(-INT64_MAX);
if (f2.a == -INT64_MAX)
return make_rational(INT64_MAX);
return make_rational(f1.b - f2.b, f2.a - f1.a);
}
bool is_required(line_t f1, line_t f2, line_t f3) const {
if (f1.a == f2.a and f1.b <= f2.b)
return false;
if (f1.a == INT64_MAX or f3.a == -INT64_MAX)
return true;
return (__int128_t)(f2.a - f1.a) * (f3.b - f2.b) <
(__int128_t)(f2.b - f1.b) * (f3.a - f2.a);
}
};
} // namespace jikka
#line 9 "foo.cpp"
#include <string>
#include <tuple>
#line 12 "foo.cpp"
int64_t solve(int64_t n_0, int64_t c_1, std::vector<int64_t> h_2) {
std::vector<int64_t> x3;
x3.push_back(0);
jikka::convex_hull_trick x4_10;
for (int32_t x5 = 0; x5 < n_0 - 1; ++x5) {
x4_10.add_line(h_2[x5], h_2[x5] * h_2[x5] + x3[x5]);
x3.push_back(c_1 + h_2[(x5 + 1)] * h_2[(x5 + 1)] +
x4_10.get_min(h_2[(x5 + 1)] * -2));
}
return x3[(n_0 - 1)];
}
int main() {
int64_t n_12 = -1;
int64_t c_13 = -1;
std::cin >> n_12;
std::vector<int64_t> h_14(n_12, -1);
std::cin >> c_13;
for (int32_t i15 = 0; i15 < n_12; ++i15) {
std::cin >> h_14[i15];
}
auto ans_16 = solve(n_12, c_13, h_14);
std::cout << ans_16 << ' ';
std::cout << '\n' << ' ';
}
提出情報
| 提出日時 |
|
| 問題 |
Z - Frog 3 |
| ユーザ |
kimiyuki |
| 言語 |
C++ (GCC 9.2.1) |
| 得点 |
100 |
| コード長 |
11441 Byte |
| 結果 |
AC |
| 実行時間 |
235 ms |
| メモリ |
35892 KiB |
ジャッジ結果
| セット名 |
All |
| 得点 / 配点 |
100 / 100 |
| 結果 |
|
| セット名 |
テストケース |
| All |
0_00, 0_01, 0_02, 1_00, 1_01, 1_02, 1_03, 1_04, 1_05, 1_06, 1_07, 1_08, 1_09, 1_10, 1_11, 1_12, 1_13, 1_14, 1_15, 1_16, 1_17, 1_18, 1_19, 1_20, 1_21, 1_22, 1_23, 1_24, 1_25, 1_26, 1_27, 1_28, 1_29, 1_30, 1_31, 1_32, 1_33, 1_34, 1_35 |
| ケース名 |
結果 |
実行時間 |
メモリ |
| 0_00 |
AC |
7 ms |
3572 KiB |
| 0_01 |
AC |
2 ms |
3456 KiB |
| 0_02 |
AC |
2 ms |
3468 KiB |
| 1_00 |
AC |
3 ms |
3416 KiB |
| 1_01 |
AC |
2 ms |
3568 KiB |
| 1_02 |
AC |
234 ms |
35892 KiB |
| 1_03 |
AC |
218 ms |
31168 KiB |
| 1_04 |
AC |
235 ms |
35748 KiB |
| 1_05 |
AC |
224 ms |
32792 KiB |
| 1_06 |
AC |
125 ms |
16016 KiB |
| 1_07 |
AC |
231 ms |
35600 KiB |
| 1_08 |
AC |
207 ms |
26400 KiB |
| 1_09 |
AC |
219 ms |
32552 KiB |
| 1_10 |
AC |
225 ms |
33808 KiB |
| 1_11 |
AC |
230 ms |
33668 KiB |
| 1_12 |
AC |
226 ms |
32768 KiB |
| 1_13 |
AC |
221 ms |
29448 KiB |
| 1_14 |
AC |
210 ms |
29616 KiB |
| 1_15 |
AC |
197 ms |
27308 KiB |
| 1_16 |
AC |
155 ms |
17796 KiB |
| 1_17 |
AC |
141 ms |
16020 KiB |
| 1_18 |
AC |
131 ms |
15972 KiB |
| 1_19 |
AC |
173 ms |
26844 KiB |
| 1_20 |
AC |
149 ms |
20736 KiB |
| 1_21 |
AC |
151 ms |
19536 KiB |
| 1_22 |
AC |
133 ms |
13216 KiB |
| 1_23 |
AC |
124 ms |
13544 KiB |
| 1_24 |
AC |
124 ms |
13488 KiB |
| 1_25 |
AC |
159 ms |
21752 KiB |
| 1_26 |
AC |
185 ms |
24740 KiB |
| 1_27 |
AC |
136 ms |
14428 KiB |
| 1_28 |
AC |
165 ms |
23252 KiB |
| 1_29 |
AC |
147 ms |
16544 KiB |
| 1_30 |
AC |
194 ms |
23784 KiB |
| 1_31 |
AC |
166 ms |
21512 KiB |
| 1_32 |
AC |
130 ms |
15360 KiB |
| 1_33 |
AC |
188 ms |
25176 KiB |
| 1_34 |
AC |
148 ms |
19152 KiB |
| 1_35 |
AC |
144 ms |
17384 KiB |