Berpizza (Codeforces 1468C)
Tags: Implement, data structures

Monocarp and Polycarp are working as waiters in Berpizza, a pizzeria located near the center of Bertown. Since they are waiters, their job is to serve the customers, but they choose whom they serve first differently.At the start of the working day, there are no customers at the Berpizza. They come there one by one. When a customer comes into the pizzeria, she sits and waits for Monocarp or Polycarp to serve her. Monocarp has been working in Berpizza for just two weeks, so whenever he serves a customer, he simply chooses the one who came to Berpizza first, and serves that customer. On the other hand, Polycarp is an experienced waiter at Berpizza, and he knows which customers are going to spend a lot of money at the pizzeria (and which aren't) as soon as he sees them. For each customer, Polycarp estimates the amount of money this customer can spend, and when he serves a customer, he chooses the one that is expected to leave the most money at Berpizza (in case there are several such customers, he chooses the one who came first among them). Obviously, no customer can be served twice, so Monocarp and Polycarp choose which customer to serve only among those who haven't been served yet.When the number of customers gets really high, it becomes difficult for both Monocarp and Polycarp to choose the customer they are going to serve. Your task is to write a program that makes these choices for them. Formally, your program should be able to process three types of queries:  $$$1$$$ $$$m$$$ — a customer comes to Berpizza, and Polycarp estimates the amount of money that they will spend as $$$m$$$;  $$$2$$$ — Monocarp serves a customer which came to the pizzeria first;  $$$3$$$ — Polycarp serves a customer which is expected to spend the largest amount of money at the pizzeria (if there are several such customers, the one that came to the pizzeria first is chosen). For each query of types $$$2$$$ and $$$3$$$, report the number of the customer who was served (the customers are numbered in the order they come to the pizzeria, starting from $$$1$$$).

Input: The first line contains one integer $$$q$$$ ($$$2 \le q \le 5 \cdot 10^5$$$) — the number of queries.Then $$$q$$$ lines follow, each describing a query in one of the following formats:  $$$1$$$ $$$m$$$ ($$$1 \le m \le 5 \cdot 10^5$$$) — a customer comes to Berpizza, and Polycarp estimates the amount of money that they will spend as $$$m$$$;  $$$2$$$ — Monocarp serves a customer which came to the pizzeria first;  $$$3$$$ — Polycarp serves a customer which is expected to spend the largest amount of money at the pizzeria (if there are multiple such customers, the one that came to the pizzeria first is chosen). Queries of type $$$2$$$ and $$$3$$$ are asked only when there exists at least one customer that hasn't been served yet. There is at least one query of type $$$2$$$ or $$$3$$$ in the input.

Output: For each query of type $$$2$$$ or $$$3$$$, print one integer — the number of the customer that has been served in that event. The customers are numbered in the order in which they come to the pizzeria, starting from $$$1$$$.


Sample Inputs:
8
1 8
1 10
1 6
3
2
1 9
2
3

6
1 8
1 10
1 8
3
3
3

8
1 103913
3
1 103913
1 103913
3
1 103913
1 103913
2

Sample Outputs:
2 1 3 4

2 1 3

1 2 3

Solution (Python):
import sys
import heapq
input = sys.stdin.readline
getint = lambda : int(input())
getints = lambda : [int(a) for a in input().split()]
served = []
time_cursor = 0
customer_count = 0
list_time = []
list_money = []

def add_customer(val):
    global list_time
    global customer_count
    global list_money
    global time_cursor
    global served
    list_time.append(val)
    heapq.heappush(list_money, (-val, customer_count))
    customer_count += 1

def deque_first():
    global list_time
    global customer_count
    global list_money
    global time_cursor
    global served
    while list_time[time_cursor] == -1:
        time_cursor += 1
    served.append(time_cursor + 1)
    list_time[time_cursor] = -1
    time_cursor += 1

def deque_best():
    global list_time
    global customer_count
    global list_money
    global time_cursor
    global served
    (_, idx) = heapq.heappop(list_money)
    while list_time[idx] == -1:
        (_, idx) = heapq.heappop(list_money)
    list_time[idx] = -1
    served.append(idx + 1)

def solve():
    global served
    q = getint()
    for i in range(q):
        raw = getints()
        if raw[0] == 1:
            add_customer(raw[1])
        elif raw[0] == 2:
            deque_first()
        else:
            deque_best()
    print(' '.join([str(i) for i in served]))
if __name__ == '__main__':
    solve()

Solution (Python):
from heapq import heappop, heappush
import sys
input = sys.stdin.readline
perc = 0
served = {}
pera = []
curs = 1
ans = []
for _ in range(int(input())):
    inp = input().split()
    if inp[0] == '1':
        m = int(inp[1])
        perc += 1
        heappush(pera, (-m, perc))
        served[perc] = False
    else:
        q = int(inp[0])
        if q == 2:
            while served[curs]:
                curs += 1
            served[curs] = True
            ans.append(curs)
        else:
            while served[pera[0][1]]:
                heappop(pera)
            (_, i) = heappop(pera)
            ans.append(i)
            served[i] = True
print(*ans)

Solution (Python):
from sys import stdin
from heapq import *
Q = int(stdin.readline())
customer_id = 1
pq = []
first = 1
ans = []
served = set()
for q in range(Q):
    args = stdin.readline().split()
    if args[0] == '1':
        heappush(pq, [-1 * int(args[1]), customer_id])
        customer_id += 1
    elif args[0] == '2':
        ans.append(first)
        served.add(first)
        while first in served:
            first += 1
    else:
        while pq[0][1] in served:
            heappop(pq)
        (price, c_id) = heappop(pq)
        ans.append(c_id)
        served.add(c_id)
        while first in served:
            first += 1
print(*ans)