E - Notebook Editorial by zer0star


この問題において、数列に対する操作は、末尾に対する追加・削除・参照しか行われません。よって、連結リストとして数列を管理すれば、これらの操作を定数時間で行うことができ、ノートの読み書きも末尾要素のポインタを保持するだけで済みます。

なお、この解法は、公式解説による根付き木を用いた解法と本質的に同等です。

以下にC++による例を示します。

#include <bits/extc++.h>

struct linked_list {
  struct node {
    int val;
    node* next;
    node(int val, node* next) : val(val), next(next) {}
  };

  node* head;

  linked_list() : head(nullptr) {}

  void push(int val) { head = new node(val, head); }

  void pop() {
    if (head) {
      head = head->next;
    }
  }

  int get() {
    if (head) {
      return head->val;
    } else {
      return -1;
    }
  }
};

int main() {
  int q;
  std::cin >> q;

  std::map<int, linked_list> notebook;

  linked_list a;

  for (int i = 0; i < q; ++i) {
    std::string op;
    std::cin >> op;

    if (op == "ADD") {
      int x;
      std::cin >> x;

      a.push(x);
    } else if (op == "DELETE") {
      a.pop();
    } else if (op == "SAVE") {
      int y;
      std::cin >> y;

      notebook[y] = a;
    } else if (op == "LOAD") {
      int z;
      std::cin >> z;

      a = notebook[z];
    }

    std::cout << a.get() << (i == q - 1 ? '\n' : ' ');
  }
}

posted:
last update: