Submission #1572946


Source Code Expand

#include <cstdio>
#include <cassert>
#include <cmath>
#include <cstring>

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <stack>
#include <queue>

#include <tuple>

#define getchar getchar_unlocked
#define putchar putchar_unlocked

#define _rep(_1, _2, _3, _4, name, ...) name
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))
#define rep(...) _rep(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)

using namespace std;

using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f80 = long double;

int get_int() {
  int c, n;
  while ((c = getchar()) < '0');
  n = c - '0';
  while ((c = getchar()) >= '0') n = n * 10 + (c - '0');
  return n;
}

template <typename T>
class PHeap {
  /*
  - Running Times: N = 10 ** 7
    - Ascend:  0.709 seconds
    - Descend: 0.249 seconds
    - Random:  15.6 seconds
  */
private:
  static constexpr T Inf = (T(1) << (sizeof(T) * 8 - 2)) - 1;
  struct Node {
    Node() {}
    Node(T v) : elem(v), sibling(nullptr), next(nullptr) {}
    T elem; Node *sibling, *next;
    static Node* merge(Node* l, Node* r) {
      if (!l) return r;
      if (!r) return l;
      if (l->elem > r->elem) swap(l, r);
      r->next = l->sibling;
      l->sibling = r;
      return l;
    };
    static Node* merge_list(Node* root) {
      if (!root->sibling) return nullptr;
      Node *a = root->sibling; root = nullptr;
      while (a) {
        Node *b = a->next, *na = nullptr;
        a->next = nullptr;
        if (b) na = b->next, b->next = nullptr;
        a = merge(a, b);
        a->next = root, root = a, a = na;
      }
      Node* s = root->next; root->next = nullptr;
      while (s) {
        Node* u = s->next; s->next = nullptr;
        root = merge(root, s);
        s = u;
      }
      return root;
    }
  };

public:
  class Allocator { // ...
  public:
    Allocator(int N) : N(N), nodes(N), unused(N) { clear_all(); }
    void clear_all() {
      for (int i = 0; i < N; ++i) unused[i] = i;
      unused_pos = 0;
    }
    Node* new_node(T v) { return &(nodes[ unused[unused_pos++] ] = Node(v)); }
    void pop(Node* p) { unused[--unused_pos] = p - nodes.data(); }
  private:
    int N;
    vector<Node> nodes;
    vector<int> unused; int unused_pos;
  };

public:
  PHeap() : root(nullptr) {}
  const T top() const { return root->elem; }
  const T second() {
    return (root->sibling = Node::merge_list(root)) ? root->sibling->elem : Inf;
  }
  bool empty() const { return !root; }
  void push(T v, Allocator& al) { root = Node::merge(root, al.new_node(v)); }
  void meld(PHeap& rhs) { root = Node::merge(root, rhs.root); }
  void pop(Allocator& al) { al.pop(root); root = Node::merge_list(root); }

private:
  Node* root;
};

template <typename T>
i64 optimal_alphabetic_tree(const vector<T>& vs) {
  /*
  - Random:
    - 10 ** 6: 1.387 seconds
    - 10 ** 7: 21.61 seconds
  */
  static constexpr T Inf = (T(1) << (sizeof(T) * 8 - 2)) - 1;
  const int N = vs.size();
  if (N <= 1) return 0;

  vector<T> A(N + 2);
  A[0] = A[N + 1] = Inf;
  for (int i = 1; i <= N; ++i) A[i] = vs[i - 1];

  using Heap = PHeap<T>;
  vector<Heap> heaps(N + 1);
  auto alloc = typename Heap::Allocator(N - 1);
  auto pop = [&] (int k) { heaps[k].pop(alloc); };
  auto push = [&] (int k, T v) { heaps[k].push(v, alloc); };

  vector<int> L(N + 2), R(N + 1);
  vector<T> best(N + 1);

  using P = pair<i64, int>;
  priority_queue< P, vector<P>, greater<P> > que;

  for (int i = 0; i < N + 1; ++i) {
    L[i] = i - 1, R[i] = i + 1;
    best[i] = A[i] + A[i + 1];
    que.emplace(best[i], i);
  }

  auto merge = [&] (int l, int r) {
    heaps[l].meld(heaps[r]);
    R[l] = R[r], L[R[r]] = l, best[r] = 2 * Inf + 1;
    return l;
  };

  i64 ret = 0;
  for (int remaining = N - 1; remaining; --remaining) {
    T w; int k;
    do { tie(w, k) = que.top(); que.pop(); } while (best[k] != w);
    ret += w; 

    int f = 0;
    if (A[k] + A[R[k]] == w) f |= 3;
    else if (heaps[k].top() + A[R[k]] == w) f |= 2, pop(k);
    else if (A[k] + heaps[k].top() == w) f |= 1, pop(k);
    else pop(k), pop(k);

    push(k, w);
    if (f & 1) k = merge(L[k], k);
    if (f & 2) k = merge(k, R[k]);

    T new_w = A[k] + A[R[k]];
    new_w = min(new_w, min(A[k], A[R[k]]) + heaps[k].top());
    new_w = min(new_w, heaps[k].top() + heaps[k].second());
    que.emplace(best[k] = new_w, k);
  }
  return ret;
}

void solve() {
  int N;
  while (~scanf("%d", &N)) {
    vector<int> A(N); rep(i, N) A[i] = get_int();
    printf("%llu\n", optimal_alphabetic_tree<int>(A));
  }
}

int main() {
  clock_t beg = clock();
  solve();
  clock_t end = clock();
  fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);
  return 0;
}

Submission Info

Submission Time
Task C - 最適二分探索木
User Min_25
Language C++14 (GCC 5.4.1)
Score 101
Code Size 5050 Byte
Status AC
Exec Time 51 ms
Memory 7280 KB

Judge Result

Set Name Sample Dataset1 Dataset2 Dataset3
Score / Max Score 0 / 0 50 / 50 50 / 50 1 / 1
Status
AC × 1
AC × 31
AC × 61
AC × 96
Set Name Test Cases
Sample 00_sample_01.txt
Dataset1 00_sample_01.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt
Dataset2 00_sample_01.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt, 02_00.txt, 02_01.txt, 02_02.txt, 02_03.txt, 02_04.txt, 02_05.txt, 02_06.txt, 02_07.txt, 02_08.txt, 02_09.txt, 02_10.txt, 02_11.txt, 02_12.txt, 02_13.txt, 02_14.txt, 02_15.txt, 02_16.txt, 02_17.txt, 02_18.txt, 02_19.txt, 02_20.txt, 02_21.txt, 02_22.txt, 02_23.txt, 02_24.txt, 02_25.txt, 02_26.txt, 02_27.txt, 02_28.txt, 02_29.txt
Dataset3 00_sample_01.txt, 01_00.txt, 01_01.txt, 01_02.txt, 01_03.txt, 01_04.txt, 01_05.txt, 01_06.txt, 01_07.txt, 01_08.txt, 01_09.txt, 01_10.txt, 01_11.txt, 01_12.txt, 01_13.txt, 01_14.txt, 01_15.txt, 01_16.txt, 01_17.txt, 01_18.txt, 01_19.txt, 01_20.txt, 01_21.txt, 01_22.txt, 01_23.txt, 01_24.txt, 01_25.txt, 01_26.txt, 01_27.txt, 01_28.txt, 01_29.txt, 02_00.txt, 02_01.txt, 02_02.txt, 02_03.txt, 02_04.txt, 02_05.txt, 02_06.txt, 02_07.txt, 02_08.txt, 02_09.txt, 02_10.txt, 02_11.txt, 02_12.txt, 02_13.txt, 02_14.txt, 02_15.txt, 02_16.txt, 02_17.txt, 02_18.txt, 02_19.txt, 02_20.txt, 02_21.txt, 02_22.txt, 02_23.txt, 02_24.txt, 02_25.txt, 02_26.txt, 02_27.txt, 02_28.txt, 02_29.txt, 03_00.txt, 03_01.txt, 03_02.txt, 03_03.txt, 03_04.txt, 03_05.txt, 03_06.txt, 03_07.txt, 03_08.txt, 03_09.txt, 03_10.txt, 03_11.txt, 03_12.txt, 03_13.txt, 03_14.txt, 03_15.txt, 03_16.txt, 03_17.txt, 03_18.txt, 03_19.txt, 03_20.txt, 03_21.txt, 03_22.txt, 03_23.txt, 03_24.txt, 03_25.txt, 03_26.txt, 03_27.txt, 03_28.txt, 03_29.txt, 03_30.txt, 03_31.txt, 03_32.txt, 03_33.txt, 03_34.txt
Case Name Status Exec Time Memory
00_sample_01.txt AC 1 ms 256 KB
01_00.txt AC 1 ms 256 KB
01_01.txt AC 1 ms 256 KB
01_02.txt AC 1 ms 256 KB
01_03.txt AC 1 ms 256 KB
01_04.txt AC 1 ms 256 KB
01_05.txt AC 1 ms 256 KB
01_06.txt AC 1 ms 256 KB
01_07.txt AC 1 ms 256 KB
01_08.txt AC 1 ms 256 KB
01_09.txt AC 1 ms 256 KB
01_10.txt AC 1 ms 256 KB
01_11.txt AC 1 ms 256 KB
01_12.txt AC 1 ms 256 KB
01_13.txt AC 1 ms 256 KB
01_14.txt AC 1 ms 256 KB
01_15.txt AC 1 ms 256 KB
01_16.txt AC 1 ms 256 KB
01_17.txt AC 1 ms 256 KB
01_18.txt AC 1 ms 256 KB
01_19.txt AC 1 ms 256 KB
01_20.txt AC 1 ms 256 KB
01_21.txt AC 1 ms 256 KB
01_22.txt AC 1 ms 256 KB
01_23.txt AC 1 ms 256 KB
01_24.txt AC 1 ms 256 KB
01_25.txt AC 1 ms 256 KB
01_26.txt AC 1 ms 256 KB
01_27.txt AC 1 ms 256 KB
01_28.txt AC 1 ms 256 KB
01_29.txt AC 1 ms 256 KB
02_00.txt AC 2 ms 512 KB
02_01.txt AC 2 ms 512 KB
02_02.txt AC 2 ms 512 KB
02_03.txt AC 2 ms 512 KB
02_04.txt AC 2 ms 512 KB
02_05.txt AC 2 ms 512 KB
02_06.txt AC 2 ms 512 KB
02_07.txt AC 2 ms 512 KB
02_08.txt AC 2 ms 512 KB
02_09.txt AC 2 ms 512 KB
02_10.txt AC 2 ms 512 KB
02_11.txt AC 2 ms 512 KB
02_12.txt AC 2 ms 512 KB
02_13.txt AC 2 ms 512 KB
02_14.txt AC 2 ms 512 KB
02_15.txt AC 2 ms 512 KB
02_16.txt AC 2 ms 512 KB
02_17.txt AC 2 ms 512 KB
02_18.txt AC 2 ms 512 KB
02_19.txt AC 2 ms 512 KB
02_20.txt AC 2 ms 512 KB
02_21.txt AC 2 ms 512 KB
02_22.txt AC 2 ms 512 KB
02_23.txt AC 2 ms 512 KB
02_24.txt AC 2 ms 512 KB
02_25.txt AC 2 ms 512 KB
02_26.txt AC 2 ms 512 KB
02_27.txt AC 2 ms 512 KB
02_28.txt AC 2 ms 512 KB
02_29.txt AC 2 ms 512 KB
03_00.txt AC 47 ms 5620 KB
03_01.txt AC 47 ms 5620 KB
03_02.txt AC 46 ms 5620 KB
03_03.txt AC 47 ms 5620 KB
03_04.txt AC 47 ms 5620 KB
03_05.txt AC 37 ms 5744 KB
03_06.txt AC 44 ms 5620 KB
03_07.txt AC 47 ms 5620 KB
03_08.txt AC 48 ms 5620 KB
03_09.txt AC 48 ms 5620 KB
03_10.txt AC 48 ms 5620 KB
03_11.txt AC 45 ms 7280 KB
03_12.txt AC 48 ms 7152 KB
03_13.txt AC 49 ms 5620 KB
03_14.txt AC 49 ms 5620 KB
03_15.txt AC 49 ms 5620 KB
03_16.txt AC 47 ms 5620 KB
03_17.txt AC 46 ms 5872 KB
03_18.txt AC 47 ms 5620 KB
03_19.txt AC 49 ms 7152 KB
03_20.txt AC 50 ms 5620 KB
03_21.txt AC 50 ms 7280 KB
03_22.txt AC 48 ms 5620 KB
03_23.txt AC 49 ms 5872 KB
03_24.txt AC 49 ms 5620 KB
03_25.txt AC 51 ms 5620 KB
03_26.txt AC 51 ms 7280 KB
03_27.txt AC 50 ms 5620 KB
03_28.txt AC 49 ms 5620 KB
03_29.txt AC 50 ms 5744 KB
03_30.txt AC 50 ms 7152 KB
03_31.txt AC 50 ms 5620 KB
03_32.txt AC 51 ms 5620 KB
03_33.txt AC 50 ms 5620 KB
03_34.txt AC 49 ms 5620 KB