E - Insert or Erase Editorial by TOMWT
std::listbrief (usage) introduction for std::list
std::list
is a container that supports constant time insertion and removal of elements from anywhere in the container. Fast random access is not supported. It is usually implemented as a doubly-linked list.—— cppreference
If we use std::list
, our code will be a lot shorter and more readable than writing a list by hand.
I’m not going to introduce everything in details including .size()
and .clear()
. I’ll only tell you how it is stronger than a vector
.
.insert()
or.emplace()
: When you write.emplace(x,y)
, wherex
is an iterator pointing to an element in the same list, it means create an element equal toy
beforex
. i.e. After this operation, it will look like \(\text{[what was in front of x]}\leftrightarrow y\leftrightarrow x\). Note that the iteratorx
is a must. The time complexity is strictly \(\mathcal O(1)\)..erase()
: When you erase.erase(x)
, wherex
is an iterator pointing to an element in the same list, literally it means to remove it. After this operation, it will look like \(\text{[what was in front of x]}\leftrightarrow \text{[what was behind x]}\). The time complexity is strictly \(\mathcal O(1)\)..splice()
: It concats two lists. (This one is powerful, but is not used in this problem.)
implementation
You know, we have to know its iterator if we want to process around an element, so we need to store its iterator for each number. Note unlike vector
, an iterator never gets spoil unless it’s deleted.
int n,q,a;list<int>qwq;map<int,list<int>::iterator>mmp;
main()
{
for(read(n);n--;read(a),qwq.emplace_back(a),mmp[a]=--qwq.end());
read(q);
for(int o,x,y;q--;)if(read(o),o^2)
{
read(x);read(y);
list<int>::iterator it=mmp[x];++it;
qwq.emplace(it,y);
mmp[y]=--it;
}
else
{
read(x);
qwq.erase(mmp[x]);
}
for(int i:qwq)printf("%d ",i);
}
posted:
last update: