답안 #977371

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
977371 2024-05-07T19:51:49 Z duckindog Building Bridges (CEOI17_building) C++17
100 / 100
58 ms 10376 KB
#include <bits/stdc++.h>

using namespace std;

const int N = 100'000 + 10;
const long long MAX = 1'000'000'000'000'000'000;
int n;
int h[N], w[N];
long long d[N];

struct Line { 
  long long a, b;

  Line() : a(0), b(MAX) {}
  Line(long long a, long long b) : a(a), b(b) {}

  double x(const auto& rhs) { return 1.0 * (b - rhs.b) / (rhs.a - a); }
  long long cal(long long x) { return a * x + b; }
} f[N << 2];
vector<int> rrh;

void insert(int s, int l, int r, Line line) { 
  if (l == r) { 
    if (f[s].cal(rrh[l - 1]) > line.cal(rrh[l - 1])) f[s] = line;
    return;
  }
  int mid = l + r >> 1;
  if (f[s].cal(rrh[mid - 1]) > line.cal(rrh[mid - 1])) swap(f[s], line);
  if (f[s].a <= line.a) insert(s << 1, l, mid, line);
  else insert(s << 1 | 1, mid + 1, r, line);
}

long long query(int s, int l, int r, int i) { 
  if (i < l || i > r) return MAX;
  if (l == r) return f[s].cal(rrh[i - 1]);
  int mid = l + r >> 1;
  if (i <= mid) return min(f[s].cal(rrh[i - 1]), query(s << 1, l, mid, i));
  return min(f[s].cal(rrh[i - 1]), query(s << 1 | 1, mid + 1, r, i));
}

long long dp[N];

int32_t main() { 
  cin.tie(0)->sync_with_stdio(0);

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

  for (int i = 1; i <= n; ++i) d[i] = d[i - 1] + w[i];

  rrh = vector<int>(h + 1, h + n + 1);
  sort(rrh.begin(), rrh.end());
  rrh.resize(unique(rrh.begin(), rrh.end()) - rrh.begin());

  insert(1, 1, rrh.size(), {-2 * h[1], 1ll * h[1] * h[1] - d[1]});
  
  for (int i = 2; i <= n; ++i) { 
    int it = lower_bound(rrh.begin(), rrh.end(), h[i]) - rrh.begin() + 1;
    dp[i] = query(1, 1, rrh.size(), it) + 1ll * h[i] * h[i] + d[i - 1];
    insert(1, 1, rrh.size(), {-2 * h[i], 1ll * h[i] * h[i] - d[i] + dp[i]});
  }

  cout << dp[n] << "\n";
}

Compilation message

building.cpp:17:18: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
   17 |   double x(const auto& rhs) { return 1.0 * (b - rhs.b) / (rhs.a - a); }
      |                  ^~~~
building.cpp: In function 'void insert(int, int, int, Line)':
building.cpp:27:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   27 |   int mid = l + r >> 1;
      |             ~~^~~
building.cpp: In function 'long long int query(int, int, int, int)':
building.cpp:36:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   36 |   int mid = l + r >> 1;
      |             ~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 8540 KB Output is correct
2 Correct 2 ms 8540 KB Output is correct
3 Correct 1 ms 8540 KB Output is correct
4 Correct 3 ms 8540 KB Output is correct
5 Correct 2 ms 8540 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 48 ms 9464 KB Output is correct
2 Correct 49 ms 9304 KB Output is correct
3 Correct 46 ms 9308 KB Output is correct
4 Correct 40 ms 9308 KB Output is correct
5 Correct 33 ms 9304 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 8540 KB Output is correct
2 Correct 2 ms 8540 KB Output is correct
3 Correct 1 ms 8540 KB Output is correct
4 Correct 3 ms 8540 KB Output is correct
5 Correct 2 ms 8540 KB Output is correct
6 Correct 48 ms 9464 KB Output is correct
7 Correct 49 ms 9304 KB Output is correct
8 Correct 46 ms 9308 KB Output is correct
9 Correct 40 ms 9308 KB Output is correct
10 Correct 33 ms 9304 KB Output is correct
11 Correct 58 ms 9308 KB Output is correct
12 Correct 55 ms 9308 KB Output is correct
13 Correct 39 ms 9308 KB Output is correct
14 Correct 55 ms 9396 KB Output is correct
15 Correct 34 ms 9304 KB Output is correct
16 Correct 33 ms 9304 KB Output is correct
17 Correct 16 ms 9560 KB Output is correct
18 Correct 15 ms 10376 KB Output is correct