E - Insert or Erase 解説 by miscalculation53
(C++) std::list を用いて実装する方法公式解説 の内容は前提とします。また、C++ での実装を主に扱います。
C++ の標準ライブラリには双方向リストの機能を持つ std::list があります。std::list のメソッドのうち特によく使うのは次の \(2\) つです。
insert
: リスト上の位置をイテレータによって指定し、その位置に要素を挿入するls.insert(イテレータ, 要素)
erase
: リスト上の位置をイテレータによって指定し、その位置の要素を削除するls.erase(イテレータ)
本問では、挿入・削除を行う位置が要素の値によって指定されます。そこで、値からイテレータを得ることのできる連想配列(std::map や std::unordered_map 等)を別途用意しておけばよいです。
イテレータについては、次の記事が参考になります。
以上の内容を踏まえた C++ での実装例を下記に示します。(using namespace std;
をしている場合は std::
は不要です。)
#include <iostream>
#include <list>
#include <map>
int main()
{
// 初期状態を入力から生成
int N;
std::cin >> N;
std::list<int> ls; // 双方向リスト
std::map<int, std::list<int>::iterator> mp; // 値からリストのイテレータを得るための map
for (int i = 0; i < N; i++)
{
int a;
std::cin >> a;
ls.insert(ls.end(), a); // リストの末尾に挿入 (push_back と同じこと)
mp[a] = std::prev(ls.end()); // a を指すイテレータを記録
}
// クエリに答える
int Q;
std::cin >> Q;
while (Q--)
{
int t;
std::cin >> t;
if (t == 1)
{
int x, y;
std::cin >> x >> y;
auto it = mp[x]; // x を指すイテレータ
ls.insert(std::next(it), y); // x の直後に y を挿入
mp[y] = std::next(it); // y を指すイテレータを記録
}
else
{
int x;
std::cin >> x;
auto it = mp[x]; // x を指すイテレータ
mp.erase(x); // x のイテレータの記録を削除
ls.erase(it); // リストから x を削除
}
}
// 答えを出力
for (int val : ls)
std::cout << val << " ";
std::cout << std::endl;
}
投稿日時:
最終更新: