結果
| 問題 |
No.180 美しいWhitespace (2)
|
| ユーザー |
rsk0315
|
| 提出日時 | 2019-01-06 18:22:24 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,266 bytes |
| コンパイル時間 | 651 ms |
| コンパイル使用メモリ | 67,472 KB |
| 最終ジャッジ日時 | 2025-01-06 20:12:45 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 27 WA * 4 |
コンパイルメッセージ
main.cpp: In function ‘int main()’:
main.cpp:108:8: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
108 | scanf("%zu", &N);
| ~~~~~^~~~~~~~~~~
main.cpp:113:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
113 | scanf("%jd %jd", &a, &b);
| ~~~~~^~~~~~~~~~~~~~~~~~~
ソースコード
#include <cstdio>
#include <cstdint>
#include <cassert>
#include <vector>
#include <algorithm>
#include <map>
template <class Tp>
class lines {
std::map<Tp, Tp> ll;
bool is_redundant(const typename std::map<Tp, Tp>::iterator& it) const {
if (it == ll.begin() || it == ll.end()) return false;
auto next = std::next(it);
if (next == ll.end()) return false;
auto prev = std::prev(it);
Tp a1, b1, a2, b2, a3, b3;
std::tie(a1, b1) = *prev;
std::tie(a2, b2) = *it;
std::tie(a3, b3) = *next;
// fprintf(stderr, "[%d, %d] [%d, %d] [%d, %d]\n", a1, b1, a2, b2, a3, b3);
return (b1-b2) * (a3-a2) <= (b2-b3) * (a2-a1);
}
public:
void append(Tp a, Tp b) {
if (ll.empty()) {
ll.emplace(a, b);
// fprintf(stderr, "(+) %dx%+d: empty set\n", a, b);
return;
}
auto it = ll.lower_bound(a);
if (it != ll.end() && it->first == a) {
if (it->second <= b) {
// fprintf(stderr, "(x) %dx%+d: one with less constant exists\n", a, b);
return;
}
it->second = b;
// fprintf(stderr, "(+) %dx%+d: update constant\n", a, b);
} else if (it == ll.begin() || it == ll.end()) {
it = ll.emplace_hint(it, a, b);
// fprintf(stderr, "(+) %dx%+d: either ends\n", a, b);
} else {
it = ll.emplace_hint(it, a, b);
if (is_redundant(it)) {
ll.erase(it);
// fprintf(stderr, "(x) %dx%+d: redundant\n", a, b);
return;
}
// fprintf(stderr, "(+) %dx%+d: normally\n", a, b);
}
auto prev = std::prev(it);
while (is_redundant(prev)) {
// fprintf(stderr, "(-) %dx%+d: prev\n", prev->first, prev->second);
ll.erase(prev);
prev = std::prev(it);
}
auto next = std::next(it);
while (is_redundant(next)) {
// fprintf(stderr, "(-) %dx%+d: next\n", next->first, next->second);
next = ll.erase(next);
}
}
Tp min_at(Tp x) const {
assert(!ll.empty());
if (ll.size() == 1) {
Tp a = ll.begin()->first;
Tp b = ll.begin()->second;
return a*x + b;
}
Tp lb = ll.begin()->first;
auto last = std::prev(ll.end());
Tp ub = last->first;
while (ub-lb > 1) {
Tp mid = (lb+ub) / 2;
auto it1 = ll.upper_bound(mid);
auto it0 = std::prev(it1);
Tp a0, b0, a1, b1;
std::tie(a0, b0) = *it0;
std::tie(a1, b1) = *it1;
((a0*x+b0 < a1*x+b1)? ub:lb) = mid;
}
auto it1 = ll.upper_bound(lb);
auto it0 = std::prev(it1);
Tp a0, b0, a1, b1;
std::tie(a0, b0) = *it0;
std::tie(a1, b1) = *it1;
return std::min(a0*x+b0, a1*x+b1);
}
void inspect() const {
// for (const auto& p: ll)
// fprintf(stderr, "%dx%+d\n", p.first, p.second);
}
};
int main() {
size_t N;
scanf("%zu", &N);
lines<intmax_t> lmin, lmax;
for (size_t i = 0; i < N; ++i) {
intmax_t a, b;
scanf("%jd %jd", &a, &b);
lmin.append(b, a);
lmax.append(-b, -a);
}
intmax_t res = 1e18;
intmax_t x = 0;
for (intmax_t i = 1; i <= 1000000; ++i) {
intmax_t y = -lmax.min_at(i) - lmin.min_at(i);
if (res > y) {
res = y;
x = i;
}
}
intmax_t m0;
{
intmax_t lb = 1;
intmax_t ub = 1e12;
while (ub-lb > 1) {
intmax_t mid = (lb+ub) >> 1;
intmax_t y0 = lmin.min_at(mid);
intmax_t y1 = lmin.min_at(mid+1);
((y0 < y1)? lb:ub) = mid;
}
m0 = lb;
}
intmax_t m1;
{
intmax_t lb = 1;
intmax_t ub = 1e12;
while (ub-lb > 1) {
intmax_t mid = (lb+ub) >> 1;
intmax_t y0 = -lmax.min_at(mid);
intmax_t y1 = -lmax.min_at(mid+1);
((y0 > y1)? lb:ub) = mid;
}
m1 = lb;
}
if (m0 > m1) std::swap(m0, m1);
intmax_t xx;
{
intmax_t lb = std::max(intmax_t(1), m0-5000000);
intmax_t ub = m1 + 5000000;
while (ub-lb > 1) {
intmax_t mid = (lb+ub) >> 1;
intmax_t y0 = -lmax.min_at(mid) - lmin.min_at(mid);
intmax_t y1 = -lmax.min_at(mid+1) - lmin.min_at(mid+1);
((y0 > y1)? lb:ub) = mid;
}
xx = lb;
}
for (intmax_t i = -500000; i <= 1000000; ++i) {
intmax_t j = xx+i;
if (j < 1) continue;
intmax_t y = -lmax.min_at(j) - lmin.min_at(j);
if (res > y) {
res = y;
x = j;
}
}
printf("%jd\n", x);
}
rsk0315