This is another problem about Indraneel's library. His library has one long shelf. His books are numbered and he identifies the books by their number. Each book has a distinct number.
He has lost many books, since many of his friends borrow his books and never bother to return them. He does not want to lose any more books and has decided to keep a record of all books that he lends to his friends. To make the task of borrowing a book a little difficult, he has given the following instructions to his friends: when they borrow a book, they must record in a register its position from the left among the books currently on the shelf.
Suppose there are 5 books in the library and they are arranged as follows:
26 1 42 15 3
If someone walks in and borrows the book 42, then he will record 3 in the register because this book is the third from the left on the shelf. Now the shelf looks like this:
26 1 15 3
If the next person borrow the book 3, he writes down 4 in the register since this is currently the fourth book from the left on the shelf, and so on.
Indraneel knows the initial arrangement of the books in his library at the time that he introduced the register system. After a while he examines his register and would like to know which books have been borrowed. Your task is to write a program to help Indraneel solve this problem.
Input format
The first line of the input contains a single integer M indicating the number of books in Indraneel's library. The next line contains M distinct positive integers describing the sequence in which the books are arranged on the library shelf. The third line of input contains a single integer N indicating the number of entries in the register. This, in turn, is followed by N lines (lines 4 to N+3), each containing one positive integer. The integer on line 3+i indicates the position from left of the book ith book borrowed. (You may assume that the number on line 3+i is at most M-i+1.)
Output format
N lines with one positive integer on each line. The number on line i is the book borrowed by the ith borrower.
Test Data:
You may assume that 1 ≤ M ≤ 1000000 and 1 ≤ N ≤ 4000.
Example:
Here is the sample input and output corresponding to the example discussed above.
Sample Input
5
26 1 42 15 3
2
3
4
Sample Output
42
3
@brandonator That doesn't even make sense. Why would you add cin.get() ??
In <algorithm> there is a remove_if function which squeezes all values not removed to the front maintaining the order. This works if you can get the elements by value, and not index.
If I am right, the vector::erase function performs at most O(N logN) operations while remove_if performs at most O(N) operations.
vector::erase function performs at most O(N) operations (worst case is trying to delete the front element) remove_if() traverse the entire container, so O(N)
@OP: your algorithm is O(M*N) and that's too much.
There is an easy O(N^2) were you consider only the taken books, (not sure if fast enough)
suppose that you want to borrow the K book,
If there is a J, with J<=K, that was borrowed, then you need to take the K+1 book.
All I was saying is that remove_if() isn't going to perform any better than vector::erase(). I don't think you are going to find any magic STL answer to this one. You may have to reconsider how you do it.
You might get a little better performance out of a std::deque for this.
(I don't have any time to give it any more thought than that tonight, sorry.)
Okay so your problem is the complexity of the erases. Here's an idea:
Store your data in a vector, but don't erase anything. However, also store a set<int> of every checkout processed. Then, when you read a new checkout, you just increase it's value +1 for every checkout in that set<int> that is less than or equal to the checkout you just read.
I thought the idiom moved the elements you don't want to the end and then erased them, which would be linear time for the search and then constant time for removal?
And you can't use remove/remove_if in this case, because there is no simple predicate you can provide to correctly identify the elements to erase - future removals are affected by previous ones.
For a vector, inserting to the end is not necessarily a free operation (and isn't performed in remove or remove_if), as the vector may have to be expanded. Also, say you erase aVector[5] in a 10 element vector - how would a user iterating over the elements know that the element at aVector[5] is now 'erased'? In order to erase an element from contiguous memory, all elements after it must be moved as well, making it O(n).
One could store a little more information in the vector, such as whether or not the book has been loaned out or not and then just skip those when looking for the nth book...
> @ne555
> There is an easy O(N^2) were you consider only the taken books, (not sure if fast enough)
> suppose that you want to borrow the K book,
> If there is a J, with J<=K, that was borrowed, then you need to take the K+1 book.