結果

問題 No.3613 Legendary Bread Maker
コンテスト
ユーザー tnakao0123
提出日時 2026-08-09 16:50:07
言語 C++17
(gcc 15.2.0 + boost 1.90.0)
コンパイル:
g++-15 -O2 -lm -std=c++17 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
AC  
実行時間 79 ms / 2,000 ms
+ 612µs
コード長 1,682 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 419 ms
コンパイル使用メモリ 77,540 KB
実行使用メモリ 20,028 KB
最終ジャッジ日時 2026-08-09 16:50:10
合計ジャッジ時間 2,662 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
サブタスク 配点 結果
サンプル 0 % AC * 3
小課題1 10 % AC * 5
小課題2 40 % AC * 13
小課題3 50 % AC * 23
合計 2 * 100% = 200 点
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

/* -*- coding: utf-8 -*-
 *
 * 3613.cc:  No.3613 Legendary Bread Maker - yukicoder
 */

#include<cstdio>
#include<queue>
#include<algorithm>
#include<tuple>

using namespace std;

/* constant */

const int MAX_N = 200000;

/* typedef */

using ll = long long;

struct Node {
  int v, f;
  Node *prv, *nxt;
  Node(): v(), f(), prv(), nxt() {}
  Node(int _v): v(_v), f(), prv(), nxt() {}

  void append(Node *p) { nxt = p, p->prv = this; }
  void remove() {
    f = 1;
    if (prv != nullptr) prv->nxt = nxt;
    if (nxt != nullptr) nxt->prv = prv;
  }
};

using tp3 = tuple<ll,Node*,Node*>;

/* global variables */

int as[MAX_N];
Node nodes[MAX_N];

/* subroutines */

/* main */

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) scanf("%d", as + i);

  priority_queue<tp3> q;
  for (int i = 0; i < n; i++) {
    nodes[i].v = as[i];
    if (i > 0) {
      auto *p0 = nodes + (i - 1), *p1 = nodes + i;
      p0->append(p1);
      q.push({-(ll)p0->v * p1->v, p0, p1});
    }
  }

  auto *head = nodes, *tail = nodes + (n - 1);
  ll sum = 0;

  while (! q.empty()) {
    auto [g, p0, p1] = q.top(); q.pop();
    if (p0->f || p1->f) continue;
    g = -g;

    sum += g;
    auto p = new Node(p0->v + p1->v);
    p0->remove();
    p1->remove();
    while (head != tail && head->f) head = head->nxt;
    while (tail != head && tail->f) tail = tail->prv;
    if (head == tail && head->f) break;

    if (head->v <= tail->v) {
      p->append(head);
      q.push({-(ll)p->v * head->v, p, head});
      head = p;
    }
    else {
      tail->append(p);
      q.push({-(ll)tail->v * p->v, tail, p});
      tail = p;
    }
  }

  printf("%lld\n", sum);
  
  return 0;
}

0