Corresponding poj question: Click to open the link
Black Box
Time limit:1000 ms
Memory limit:10000kb
64bit Io format:% I64d & % i64usubmit status
Description
Our black box represents a primitive database. it can save an integer array and has a special I variable. at the initial moment black box is empty and I equals 0. this black box processes a sequence of commands (transactions ). there are two types of transactions:
Add (x): Put element x into black box;
Get: Increase I by 1 and give an I-Minimum Out Of All integers containing in the black box. keep in mind that I-minimum is a number located at I-th place after Black Box elements sorting by non-descending.
Let us examine a possible sequence of 11 transactions:
Example 1
N Transaction i Black Box contents after transaction Answer (elements are arranged by non-descending) 1 ADD(3) 0 3 2 GET 1 3 3 3 ADD(1) 1 1, 3 4 GET 2 1, 3 3 5 ADD(-4) 2 -4, 1, 3 6 ADD(2) 2 -4, 1, 2, 3 7 ADD(8) 2 -4, 1, 2, 3, 8 8 ADD(-1000) 2 -1000, -4, 1, 2, 3, 8 9 GET 3 -1000, -4, 1, 2, 3, 8 1 10 GET 4 -1000, -4, 1, 2, 3, 8 2 11 ADD(2) 4 -1000, -4, 1, 2, 2, 3, 8
It is required to work out an efficient algorithm which treats a given sequence of transactions. The maximum number of ADD and get transactions: 30000 of each type.
Let us describe the sequence of transactions by two integer Arrays:
1. A (1), a (2 ),..., A (m): a sequence of elements which are being encoded into black box. A values are integers not exceeding 2 000 000 000 by their absolute value, m <= 30000. for the example we have A = (3, 1,-4, 2, 8,-1000, 2 ).
2. U (1), u (2 ),..., U (n): a sequence setting a number of elements which are being encoded into black box at the moment of first, second ,... and N-transaction get. for the example we have u = (1, 2, 6, 6 ).
The Black Box algorithm supposes that natural number sequence U (1), u (2 ),..., U (n) is sorted in non-descending order, n <= m and for each P (1 <= P <= N) an inequality P <= U (P) <= m is valid. it follows from the fact that for the p-element of our U sequence we perform a get transaction giving p-minimum number from our A (1 ), A (2 ),..., A (U (p) sequence.
Input
Input contains (in given order): m, n, A (1), a (2 ),..., A (M), u (1), u (2 ),..., U (n ). all numbers are divided by spaces and (or) carriage return characters.
Output
Write to the output black box answers sequence for a given sequence of transactions, one number each line.
Sample Input
7 43 1 -4 2 8 -1000 21 2 6 6
Sample output
3312
Given the number of M, you can insert a sequence number each time. Then, N indicates that a number is output when the number is inserted. The first output sequence is the smallest, the second small in the second output sequence ...... And so on until n is output.
Analysis: when the output is the smallest output first, and then the second smallest output, it is equivalent to outputting the values in an ordered sequence in sequence. However, because the sequence is not fixed, but constantly updated, it cannot be implemented using arrays. We can use the priority queue.
Define two priority queues. One is used to store the first K small numbers. The first is a large number, and the second is a decimal number. The second is the k + 1 to the largest number, the large number is behind. Each time you get a number, first judge that the number of the first priority queue is less than K. If the number is less than K, the number is directly pushed to the first queue. If the number is more than K, determine the size of this number and the first number in the first priority queue: If it is larger than the first number, it is pushed into the second priority queue; if it is smaller than the first number, the first element of the first priority queue is pushed to the second queue, and the new number is pushed to the first priority queue.
Others' questions are enlightening ~
The two priority queues are as follows:
# Include <cstdio> # include <cstdlib> # include <cmath> # include <map> # include <set> # include <queue> # include <stack> # include <vector> # include <algorithm> # include <cstring> # include <string> # include <iostream> const int maxn = 30000 + 10; using namespace STD; int A [maxn]; int B [maxn]; int main () {freopen ("in.txt", "r", stdin); int n, m; while (scanf ("% d", & N, & M) = 2) {priority_queue <int> q1; // maximum priority_queue of the top element of the stack <int, vector <int>, grea TER <int> Q2; // minimum int I, j; for (I = 1; I <= N; I ++) {scanf ("% d", & A [I]) ;}for (I = 1; I <= m; I ++) {scanf ("% d ", & B [I]);} j = 1; int K = 1; // number of small K numbers to be output for (I = 1; I <= N; I ++) {// put the number into the stack if (q1.size () <k) q1.push (A [I]); // If Q1 does not reach K, put the number into q1else {// otherwise, compare it with the first element of the [I] and Q1 teams, the smaller one is Q1, and the larger one is q2int T = q1.top (); if (A [I]> = T) q2.push (A [I]); else {q2.push (t); q1.pop (); q1.push (A [I]);} while (I = B [J]) // After the number of B [J] is placed, the number of K must be output, that is, the first element of the q1 team {printf ("% d \ n", q1.top (); k ++; J ++; If (! Q2.empty () {// Q1 Length + 1, get the minimum element from Q2 and put it into Q1. Continue to judge whether the element is placed in q1.push (q2.top () for the second [J ()); q2.pop () ;}}} return 0 ;}