<think>We are going to solve the problem in C++ with the following steps:
1. We have up to 100 queries of type 2 (by employee ID) and up to 10^5 tickets and 10^5 queries.
2. We note that the employee IDs are strings of the form "PATxxxxxx", and there are up to 10^5 tickets, so we can have duplicate employee IDs (same employee can have multiple tickets).
Requirements:
- For action "1 x": We need to find the smallest ticket number >= x. If found, output the employee ID of that ticket. Otherwise, output "ERROR".
- For action "2 y": We output all winning ticket numbers for employee y in the order of input (if the employee doesn't exist, output "ERROR"; if no winning ticket, output empty line).
- For action "3 x": We output the employee ID of the ticket with number x. If no such ticket, output "ERROR".
Important: A ticket can win multiple times. But note: the same ticket number might appear multiple times? The problem says "each ticket has a unique integer", so each ticket number is unique.
However, note: the same employee can have multiple tickets (with different numbers). And the same ticket (by number) cannot be repeated.
Approach:
We have two main challenges:
1. Efficiently answering the "1 x" and "3 x" queries which require looking up by ticket number.
2. For the "2 y" queries, we have to output the winning tickets for an employee in the order of input.
Since there are at most 100 queries of type 2, we can do the following:
We will store:
- A mapping from ticket number to employee ID (for unique tickets, so we can do a direct lookup for type 3 and also for type 1 we need the employee).
- For type 1 queries: we need to quickly find the smallest ticket number >= x. We can use a sorted set (or set) and then use lower_bound.
However, note: we have to consider that the same ticket number might be declared as winner multiple times? But the problem says "a ticket can win multiple times", but note that the same ticket number is unique. So when we look for the ticket, we are looking for the ticket number that exists.
Steps:
1. We read N, then N lines of (employee_id, ticket_number).
2. We note: we have to preserve the order of tickets for each employee? Only for the output in type 2: we are to output in the same order as input. But note: the input order of tickets for an employee might be scattered.
However, the problem says: "output all winning ticket numbers held by this employee in the same order of input".
So we need to record for each employee, the list of tickets (the ticket numbers) that they have, in the order they appear in the input. But also, we need to mark which of these tickets have won.
How about:
- We create a global vector that records the entire input? But we have 10^5 tickets, and then for each employee we want to output the winning ones in the order of input.
- Alternatively, we can store for each employee, a vector of pairs (ticket_number, won_count) but note: we don't need the count, we need to output the ticket number every time it wins? But the problem says "all his/her tickets that have already won". And since a ticket can win multiple times, we have to record each win?
However, note the problem: "Declare that the ticket with a specific number x wins." -> then we mark that ticket as having won. But the problem says "a ticket can win multiple times", meaning the same ticket can be declared winner multiple times? Then for an employee, we want to output the same ticket number multiple times?
But the output for type 2: we are to output the winning ticket numbers. The problem says: "output all winning ticket numbers held by this employee in the same order of input".
Interpretation:
- If a ticket wins multiple times, then for the employee, we should output that ticket number multiple times? But note: the problem says "ticket numbers", and the same ticket number is printed multiple times?
However, the sample input does not show multiple wins for the same ticket. But the problem says "a ticket can win multiple times", so we must account for that.
How to record wins per ticket? We can have:
- We maintain a set (or map) for the winning events? But note: the type 2 query asks for all winning tickets (by the employee) that have ever won (and if won multiple times, then we output the ticket number multiple times?).
However, the problem does not specify the order of multiple wins. But the output order is defined as the same order as input. So we are to output the ticket numbers in the order that the tickets were originally input? And if the same ticket wins multiple times, then each win event should be recorded? But the problem says "all his/her tickets that have already won" - meaning that the ticket has won at least once? Then we output the ticket number once for each win event? Or one time per win event?
Let me read the problem again: "output all winning ticket numbers held by this employee in the same order of input"
This is ambiguous. But note: the sample does not have multiple wins for the same ticket. However, the problem states: "a ticket can win multiple times", so we must output the ticket number multiple times?
But the problem says "in the same order of input". The input order of what? The tickets. So if an employee has two tickets: [1, 2] in that order. Then if ticket 1 wins twice and ticket 2 wins once, then the output should be: 1, 1, 2? or 1, 2?
The problem says: "all winning ticket numbers" and then "in the same order of input". It likely means: for each ticket (by the input order) that has won at least once, we output the ticket number? But then what about multiple wins?
However, note: the problem says "ticket numbers", and each win event is for a specific ticket. But the type 2 query does not specify an event, it just asks for the employee's winning tickets.
The sample output for type 2:
2 PAT000008 -> outputs 15
2 PAT000001 -> outputs (empty) then later after wins, outputs "1 2"
After the wins:
3 1 -> wins, then 2 PAT000001 outputs "1 2"
But note: the employee PAT000001 has two tickets: 1 and 2. Both have won at least once? Then we output the ticket numbers in the order of input: first ticket 1, then ticket 2? So we output "1 2" (on the same line? but the sample output has two numbers: "1 2" meaning two numbers?).
However, the sample output for the last query:
2 PAT000001
outputs: 1 2
So it's two numbers. But note: the employee has two winning tickets: 1 and 2, each won at least once. And we output the ticket numbers in the order of the input (the first ticket of PAT000001 is 1, then the second is 2). We do not output the same ticket number multiple times even if it won multiple times?
The problem says: "all winning ticket numbers" - meaning each distinct winning ticket? Or every win event?
But the sample:
The employee PAT000001 has two tickets: 1 and 2. Both have won. So we output both. And the output is "1 2", meaning two numbers.
So it seems we are to output each distinct winning ticket (by its number) that the employee has, and we output them in the order of the input (the order in which the tickets were given to the employee in the input). And if the same ticket wins multiple times, we still output the ticket number only once?
However, the problem says: "a ticket can win multiple times", but then the type 2 query does not ask for the win events, it asks for the tickets that have won. So if a ticket has won at least once, we list it once.
Therefore, for each employee, we want to record the set of distinct ticket numbers that have won? But then we have to output in the order of input. How?
We can do:
- We create a mapping: employee_id -> vector of all ticket numbers that belong to this employee (in the order of input). But then we also need to know which of these tickets have won at least once.
- Alternatively, we can record for each employee, a vector of pairs: (ticket_number, has_won) and then update has_won when a win occurs. But then when we output, we traverse the vector and output the ticket_number for which has_won is true. But note: if we update the same ticket multiple times, we set has_won to true and then we don't change it. So we only output once.
- However, the problem says: "a ticket can win multiple times" but we are only required to output the ticket number once? That seems consistent with the sample.
So we will:
- Have a global set (or sorted container) for the tickets for quick lookup by number: we want to map ticket number to employee ID and also for the type 1 query we need to find the smallest ticket >= x.
- We also need to record the wins per ticket? Actually, we don't need the count of wins, we just need to know that the ticket has won at least once? Because for type 2 we only output the ticket number once.
- But note: the problem says "Declare that the ticket with a specific number x wins." and we are to record that win. However, for type 2 we are only asked for the tickets that have won (at least once). So we can mark a boolean for the ticket: has_won.
Implementation:
Let:
- `ticketOwner`: a map from ticket_number to employee_id (string). But note: the same ticket number is unique.
- `employeeTickets`: a map from employee_id to a vector of the ticket numbers that employee has (in the order of input). But we also want to mark which ones have won? Alternatively, we can have a separate set for winning tickets? Or we can have a set for winning tickets?
However, for type 2: we need to output the winning tickets for an employee in the order of input. So:
We can have:
map<string, vector<long long>> employeeTickets; // employee_id -> list of ticket numbers (in input order)
set<long long> winningTickets; // to record which tickets have won at least once? Actually, we don't need the entire set, we only need to know per employee. But we can also update per employee.
Alternatively, we can have a boolean flag per ticket? But we have 10^5 tickets, and then for each employee we traverse the vector and check if the ticket is in a global winning set? That would be O(n) per type 2 query, and we have at most 100 such queries, so worst-case 100 * (number of tickets per employee) which might be 100 * (max tickets per employee). The total tickets is 10^5, so worst-case an employee has 10^5 tickets. Then 100*10^5 = 10^7, which is acceptable.
But note: we are storing the vector of tickets per employee. We can also have:
map<string, vector<long long>> employeeTickets; // all tickets of the employee (in order)
set<long long> globalWinningTickets; // set of all tickets that have won at least once.
Then for a type 2 query for employee y:
if employeeTickets does not have y, output "ERROR"
else, traverse the vector of tickets for y, and for each ticket, if it is in globalWinningTickets, then output it? But we have to output in the order of the vector (which is the input order). And we output each winning ticket only once (even if it won multiple times, we only mark it as won).
But note: the problem says "a ticket can win multiple times", but we are only outputting the ticket number once. So that matches.
Steps for actions:
Type 1: "1 x"
We need to find the smallest ticket number >= x that exists.
We can maintain a sorted set (or multiset) of all ticket numbers? But note: the tickets are unique, so set is enough.
Let `ticketSet` be a set<long long> of all ticket numbers.
Then:
auto it = ticketSet.lower_bound(x);
if (it == ticketSet.end()) -> output "ERROR"
else -> output the employee_id for ticket *it. We have a map: ticketToOwner[*it] (which we can precompute).
Type 2: "2 y"
If employeeTickets.find(y) == employeeTickets.end() -> "ERROR"
Else:
vector<long long> tickets = employeeTickets[y];
for each ticket in tickets:
if (globalWinningTickets.find(ticket) != globalWinningTickets.end())
then output the ticket (with a space separator? but the problem says output the numbers in the same line, space separated? and if none, output empty line)
But note: we must output the numbers in the order of the vector.
However, the problem says: output the winning ticket numbers. We must output them in the order of input. And the vector is in the order of input.
Type 3: "3 x"
If the ticket x exists? Check in ticketSet? Actually, we have a map from ticket number to employee ID: ticketToOwner.
If ticketToOwner.find(x) == ticketToOwner.end() -> "ERROR"
Else -> output ticketToOwner[x]
Also, we must mark that ticket x has won? So we add x to globalWinningTickets? But note: what if the same ticket wins again? Then we mark it again? But we are using a set, so duplicate adds are ignored. That's what we want: we only care that it has won at least once.
However, note: the problem says "a ticket can win multiple times", but for type 2 we only output the ticket once. So we don't need to record the count.
But wait: what about type 1? When we do a type 1, we also mark the winning ticket?
Actually, the problem says:
Action 1: "Announce a lucky number x, and the winner is then the smallest number that is greater than or equal to x." -> we must mark that ticket as having won?
Action 3: "Declare that the ticket with a specific number x wins."
So both action 1 and action 3 declare a winner. Therefore, after we find the ticket in action 1, we must mark that ticket as having won (by adding to globalWinningTickets).
However, note: the problem says "For actions of type 1 and 3, output the employee ID holding the winning ticket." and then we mark the ticket as won?
Therefore, we must update globalWinningTickets in both action 1 and action 3.
Steps for action 1:
- Find the ticket number t (smallest >= x) in the set of tickets.
- If found, output the employee ID for t.
- Then mark t as won: globalWinningTickets.insert(t);
- If not found, output "ERROR"
Steps for action 3:
- If the ticket x exists, output the employee ID and then mark x as won: globalWinningTickets.insert(x);
- Else, output "ERROR"
But note: what if the same ticket is declared winner again? Then we mark it again? But globalWinningTickets is a set, so duplicate inserts are harmless.
However, we must note: the problem says "a ticket can win multiple times", but we are only storing that it has won at least once. That is sufficient for the type 2 output.
Implementation details:
We need:
set<long long> ticketSet; // all ticket numbers
map<long long, string> ticketToOwner; // maps ticket number to employee ID
set<long long> globalWinningTickets; // tickets that have won at least once
map<string, vector<long long>> employeeTickets; // for each employee, the list of ticket numbers (in input order)
How to build employeeTickets?
When reading the input, for each line (employee_id, ticket_number):
ticketSet.insert(ticket_number);
ticketToOwner[ticket_number] = employee_id;
employeeTickets[employee_id].push_back(ticket_number);
Note: the employee_id is given as a string. We assume the same employee_id string for the same employee.
However, note: the problem says "employee ID in the format PAT followed by a six-digit number", so they are strings.
But caution: what if the same ticket number appears twice? The problem says "each of which has a unique integer", so no duplicate.
Then we process Q queries.
For each query:
if type == 1:
long long x;
auto it = ticketSet.lower_bound(x);
if (it == ticketSet.end()) {
cout << "ERROR\n";
} else {
long long ticket = *it;
cout << ticketToOwner[ticket] << '\n';
globalWinningTickets.insert(ticket); // mark as won
}
if type == 2:
string y;
// read y
if (employeeTickets.find(y) == employeeTickets.end()) {
cout << "ERROR\n";
} else {
vector<long long> tickets = employeeTickets[y];
vector<long long> wins;
for (auto t : tickets) {
if (globalWinningTickets.find(t) != globalWinningTickets.end()) {
wins.push_back(t);
}
}
// Now output the wins: if wins is empty, output an empty line?
// Otherwise, output the wins in the order of the vector (which is the input order) and space separated?
for (int i = 0; i < wins.size(); i++) {
if (i > 0) cout << ' ';
cout << wins[i];
}
cout << '\n';
}
if type == 3:
long long x;
if (ticketSet.find(x) == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[x] << '\n';
globalWinningTickets.insert(x);
}
However, note: the set `ticketSet` is a sorted set. We use it for type 1 and type 3 to check existence? Actually, for type 3 we can use ticketSet.find? But we have a map ticketToOwner, so we can check existence by ticketToOwner.find(x) != ticketToOwner.end()? But note: we built ticketSet and ticketToOwner from the same input. So if a ticket is in ticketSet, it is in ticketToOwner.
Alternatively, we can use only ticketToOwner to check existence? Yes.
So we can avoid maintaining ticketSet? Actually, no: for type 1 we need lower_bound on the set of tickets. So we need the set.
But note: we have a set of all ticket numbers: ticketSet. We can use that for lower_bound.
However, we have to update the set? The set is fixed: we read all tickets at the beginning.
But what if we have duplicate tickets? The problem says unique, so no.
But note: the problem says the ticket numbers are unique.
Therefore, we can do:
set<long long> ticketSet; // all ticket numbers
And we use it for type 1 and type 3? Actually, for type 3 we can also use the set to check existence? But we have ticketToOwner: we can check with ticketToOwner.count(x) or ticketSet.count(x). Both are O(log n). We can use either.
However, for type 1 we require the set for lower_bound.
Let's code accordingly.
But note: the constraints: N, Q up to 10^5. The set operations are O(log n) per operation, so total O((N+Q) * log N) which is acceptable.
However, the type 2 queries: we are iterating over the entire list of tickets for an employee. The worst-case employee might have 10^5 tickets, and we have at most 100 type 2 queries, so worst-case 100 * 10^5 = 10^7, which is acceptable.
But note: we are building a vector for each employee. The total memory is the total number of tickets (10^5). So we are safe.
However, we must be cautious: the employeeTickets map: the key is a string (about 9 characters) and the value is a vector. The total number of employees might be up to 10^5? But the problem says: each employee ID is given. But the same employee can appear multiple times. So the map employeeTickets will have one entry per distinct employee, and the vector for that employee will have all the tickets.
Total memory: the vectors: total 10^5 long longs (about 800KB) and the set: 10^5 long longs (about 800KB) and the map: 10^5 entries of (long long -> string) and the string is about 9 bytes? Actually, the string is variable: "PAT000001" is 9 characters. But we store the same employee ID multiple times? In the map employeeTickets, we store the employee ID as the key, and then the vector. The ticketToOwner: each ticket has a string, so 10^5 strings. But each string is the same for the same employee? Actually, we store the same string multiple times. We can avoid that by storing the employee ID as a string and then in the map employeeTickets we use the same string? But the keys in the map are strings, and the values are vectors.
Alternatively, we can use a map from string to vector, and for the ticketToOwner, we can store the employee ID as a pointer to the same string? But that is complex. Instead, we can store the employee ID string once in the map and then use a reference? But in C++ we are storing copies.
Total memory for strings:
Each employee ID is 9 characters (so 9 bytes per string).
How many distinct employees? In the worst-case, each ticket belongs to a distinct employee? Then we have 10^5 distinct employees. Then:
employeeTickets: 10^5 keys (each 9 bytes) -> 900,000 bytes for keys, and then each vector: the vector itself has a small overhead (about 24 bytes per vector) and then the data: each vector has one or more tickets. The total number of tickets is 10^5, so the total for the vectors is 10^5 * sizeof(long long) = 800,000 bytes.
ticketToOwner: 10^5 entries: key is long long (8 bytes) and value is string (9 bytes) -> 10^5 * (8+9) = 1,700,000 bytes.
globalWinningTickets: set of long long: 10^5 * 8 = 800,000 bytes? But worst-case we mark all as winning? Then 800,000 bytes.
ticketSet: set of long long: 10^5 * 8 = 800,000 bytes? (the set has overhead: each node has pointers, so about 8*3 per node? so 24 bytes per node -> 2,400,000 bytes?).
Total: about 900,000 (employeeTickets keys) + 800,000 (employeeTickets vectors data) + 1,700,000 (ticketToOwner) + 800,000 (globalWinningTickets) + 2,400,000 (ticketSet) = about 6.6 MB. Then we have the vectors for employeeTickets: each vector has a small overhead (about 24 bytes per vector) * 10^5 = 2,400,000 bytes -> total about 9 MB. And we have the input and output buffers. So 64 MB is sufficient.
But note: the set and map have node-based structures that use more memory. But 10^5 nodes is acceptable.
Code without comments (as per requirement) and we must be efficient.
Let's code accordingly.
Important: The problem says the ticket numbers can be negative and as large as 10^9 in absolute value, so we use long long.
Steps:
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <cctype>
#include <algorithm>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
set<long long> ticketSet;
map<long long, string> ticketToOwner;
set<long long> globalWinningTickets;
map<string, vector<long long>> employeeTickets;
for (int i = 0; i < N; i++) {
string emp;
long long x;
cin >> emp >> x;
ticketSet.insert(x);
ticketToOwner[x] = emp;
employeeTickets[emp].push_back(x);
}
int Q;
cin >> Q;
while (Q--) {
int type;
cin >> type;
if (type == 1) {
long long x;
cin >> x;
auto it = ticketSet.lower_bound(x);
if (it == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[*it] << '\n';
globalWinningTickets.insert(*it);
}
} else if (type == 2) {
string y;
cin >> y;
if (employeeTickets.find(y) == employeeTickets.end()) {
cout << "ERROR\n";
} else {
const vector<long long>& tickets = employeeTickets[y];
vector<long long> wins;
for (long long t : tickets) {
if (globalWinningTickets.find(t) != globalWinningTickets.end()) {
wins.push_back(t);
}
}
if (wins.empty()) {
cout << '\n';
} else {
for (int i = 0; i < wins.size(); i++) {
if (i > 0) cout << ' ';
cout << wins[i];
}
cout << '\n';
}
}
} else if (type == 3) {
long long x;
cin >> x;
if (ticketSet.find(x) == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[x] << '\n';
globalWinningTickets.insert(x);
}
}
}
return 0;
}
But note: the problem says "output the employee ID holding the winning ticket" for type 1 and 3. And for type 2, we output the winning ticket numbers (if any) in the order of input.
However, the sample input:
"1 10" -> we find the smallest ticket >=10: in the sample, the tickets are:
[ -2000, -5, 1, 2, 4, 5, 7, 15, 18, 20]
The smallest ticket >=10 is 15? But wait: 7 is less than 10, then 15 is the next.
The employee for 15 is PAT000008? -> output "PAT000008"
Then "2 PAT000008": the employee PAT000008 has two tickets: 7 and 15. And 15 has been marked as won (from the action 1). So we output 15.
Then "2 PAT000001": the employee PAT000001 has two tickets: 1 and 2. None has been marked as won? So output empty line? But the sample output for this is empty? Actually, the sample output for this is:
PAT000008
15
[empty line?]
Then the next outputs:
ERROR
ERROR
...
However, the sample output:
PAT000008
15
ERROR
...
So the empty line is printed as a blank line.
Then the next actions:
"3 -10": there is no ticket -10? -> output "ERROR"
"1 9999": no ticket >=9999 -> output "ERROR"
"1 -10": the smallest ticket >=-10: we have -2000, -5: the smallest >=-10 is -5? -> employee PAT000003 -> output "PAT000003"
Then we mark -5 as won.
Then "3 2": there is a ticket 2? -> employee PAT000001 -> output "PAT000001", and mark 2 as won.
Then "1 0": smallest ticket >=0: we have 1 -> PAT000001 -> output "PAT000001", and mark 1 as won.
Then "3 1": ticket 1 exists -> PAT000001 -> output "PAT000001", and mark 1 as won (again, but set ignores).
Then "2 PAT000001": now the employee PAT000001 has tickets [1,2]. Both have been won (1 was won by the last two actions? and 2 by the action "3 2"). So we output: first 1 then 2 -> "1 2"
Then "3 -2000": exists -> employee PAT102030 -> output "PAT102030", and mark -2000 as won.
The sample output:
PAT000008
15
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
But the sample output in the problem is:
PAT000008
15
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
So it matches.
However, note: the sample input has 11 queries, so we output 11 lines? Actually:
Query 1: "1 10" -> PAT000008 (line1)
Query 2: "2 PAT000008" -> 15 (line2) -> then we output a new line? so line2: "15" and then we have a blank line for query3?
But the problem output:
PAT000008
15
ERROR
...
How many lines?
Line1: "PAT000008"
Line2: "15"
Line3: (empty line) -> because the next query is type2 for PAT000001 which has no wins at that time -> output a blank line?
Then Line4: "ERROR"
But the sample output says:
PAT000008
15
ERROR
...
That means after the first type2 we output two lines? Actually, the first type2 outputs one line: the winning numbers (if any) and then we output a newline at the end. So for the second query (type2) we output "15" and then a newline? and then the third query (type2) outputs an empty line?
Actually, the code for type2:
if wins is empty: we output a newline (so an empty line) -> that's one line.
else: we output the numbers and then a newline -> one line.
So the output for the 11 queries:
Query1: type1 -> "PAT000008" (line1)
Query2: type2 -> output "15" (without newline? no: we output the numbers and then a newline) -> so line2: "15"
Query3: type2 -> output a newline -> line3: empty
Query4: type3 -> "ERROR" -> line4
Query5: type1 -> "ERROR" -> line5
Query6: type1 -> "PAT000003" -> line6
Query7: type3 -> "PAT000001" -> line7
Query8: type1 -> "PAT000001" -> line8
Query9: type3 -> "PAT000001" -> line9
Query10: type2 -> "1 2" -> line10
Query11: type3 -> "PAT102030" -> line11
So the output has 11 lines? But the sample output only shows 10 lines?
Actually, the sample input has 11 actions, and the sample output has:
PAT000008
15
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
That's 10 lines?
But note: the second query (type2) outputs one line: "15", and the third query (type2) outputs an empty line -> that's two lines. Then the rest: 9 lines? total 11 lines.
The problem says:
Sample Output:
PAT000008
15
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
How many lines?
Line1: PAT000008
Line2: 15
Line3: (empty)
Line4: ERROR
Line5: ERROR
Line6: PAT000003
Line7: PAT000001
Line8: PAT000001
Line9: PAT000001
Line10: 1 2
Line11: PAT102030
So 11 lines.
But the problem sample output is written as 10 lines? Actually, the blank line is represented as a blank line. So the output is:
PAT000008
15
[blank]
ERROR
ERROR
...
So the sample output in the problem has 11 lines? They just show the blank as an empty line.
Therefore, the code is as above.
Let me run the sample input with the code to see if it matches.
However, note: the sample input has:
PAT000001 1
PAT000003 5
PAT000002 4
PAT000010 20
PAT000001 2
PAT000008 7
PAT000010 18
PAT000003 -5
PAT102030 -2000
PAT000008 15
Then the queries:
11
1 10
2 PAT000008
2 PAT000001
3 -10
1 9999
1 -10
3 2
1 0
3 1
2 PAT000001
3 -2000
We have:
ticketSet: [-2000, -5, 1, 2, 4, 5, 7, 15, 18, 20]
Query1: 1 10 -> lower_bound(10) -> first element >=10: 15 -> employee PAT000008 -> output "PAT000008", and mark 15 as won.
Query2: 2 PAT000008 -> employeeTickets["PAT000008"]: [7,15] -> wins: 15 -> output "15"
Query3: 2 PAT000001 -> employeeTickets["PAT000001"]: [1,2] -> wins: none -> output empty line.
Query4: 3 -10 -> ticket -10 not found -> "ERROR"
Query5: 1 9999 -> lower_bound(9999) -> end -> "ERROR"
Query6: 1 -10 -> lower_bound(-10) -> the first >=-10:
The set: [-2000, -5, ...]
lower_bound(-10): the first element >= -10 -> -5 -> output "PAT000003", and mark -5 as won.
Query7: 3 2 -> ticket 2 exists -> employee PAT000001 -> output "PAT000001", and mark 2 as won.
Query8: 1 0 -> lower_bound(0): first >=0 -> 1 -> output "PAT000001", and mark 1 as won.
Query9: 3 1 -> exists -> output "PAT000001", mark 1 (again).
Query10: 2 PAT000001 -> tickets [1,2]: both won -> output "1 2"
Query11: 3 -2000 -> exists -> output "PAT102030", mark -2000.
Output:
PAT000008
15
[empty line]
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
So we output 11 lines.
But the problem sample output is:
PAT000008
15
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
How many lines? 10? Actually, the first two lines:
PAT000008
15
Then the third line is empty, then the rest: 8 lines? total 11.
The problem sample output is written as 10 lines? But they show 10 lines of text? Actually, they show:
Line1: PAT000008
Line2: 15
Line3: (blank) -> so they skip a line?
Then Line4: ERROR
...
So the output has 11 lines.
Therefore, we output 11 lines.
We code accordingly.
However, note: the problem says "output the employee ID holding the winning ticket" for type1 and type3, and for type2 we output the list of numbers (if any) or an empty line.
We use:
ios::sync_with_stdio(false);
cin.tie(0);
for speed.
We use long long for the ticket numbers.
Let me run with the sample to be sure.
But note: the problem says "code without comments". So we remove comments.
Final code:
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
set<long long> ticketSet;
map<long long, string> ticketToOwner;
set<long long> globalWinningTickets;
map<string, vector<long long>> employeeTickets;
for (int i = 0; i < N; i++) {
string emp;
long long x;
cin >> emp >> x;
ticketSet.insert(x);
ticketToOwner[x] = emp;
employeeTickets[emp].push_back(x);
}
int Q;
cin >> Q;
while (Q--) {
int type;
cin >> type;
if (type == 1) {
long long x;
cin >> x;
auto it = ticketSet.lower_bound(x);
if (it == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[*it] << '\n';
globalWinningTickets.insert(*it);
}
} else if (type == 2) {
string y;
cin >> y;
if (employeeTickets.find(y) == employeeTickets.end()) {
cout << "ERROR\n";
} else {
const vector<long long>& tickets = employeeTickets[y];
vector<long long> wins;
for (long long t : tickets) {
if (globalWinningTickets.find(t) != globalWinningTickets.end()) {
wins.push_back(t);
}
}
for (int i = 0; i < wins.size(); i++) {
if (i > 0) cout << ' ';
cout << wins[i];
}
cout << '\n';
}
} else if (type == 3) {
long long x;
cin >> x;
if (ticketSet.find(x) == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[x] << '\n';
globalWinningTickets.insert(x);
}
}
}
return 0;
}
This should meet the constraints.
Let me test with the sample input.
But note: the sample input has 10 tickets and 11 queries.
We'll run the sample input:
Input:
10
PAT000001 1
PAT000003 5
PAT000002 4
PAT000010 20
PAT000001 2
PAT000008 7
PAT000010 18
PAT000003 -5
PAT102030 -2000
PAT000008 15
11
1 10
2 PAT000008
2 PAT000001
3 -10
1 9999
1 -10
3 2
1 0
3 1
2 PAT000001
3 -2000
Expected output:
PAT000008
15
(empty line)
ERROR
ERROR
PAT000003
PAT000001
PAT000001
PAT000001
1 2
PAT102030
We output:
Line1: PAT000008
Line2: 15
Line3: (empty) -> so we output a newline? so it's a blank line.
Line4: ERROR
Line5: ERROR
Line6: PAT000003
Line7: PAT000001
Line8: PAT000001
Line9: PAT000001
Line10: 1 2
Line11: PAT102030
So it matches.
We note: the problem says "For actions of type 1 and 3, output the employee ID holding the winning ticket." and we do.
We note: the problem says "For actions of type 2, if the employee ID y does not exist, output ERROR. Otherwise, output all winning ticket numbers ... in the same order of input. If no ticket wins, output an empty line instead." -> we do.
We are using sets and maps which are efficient.
We hope it meets the constraints: 10^5 operations, each set/map operation is O(log n) so total O((N+Q) * log N) which is about (10^5+10^5)*log2(10^5) = 200000 * 17 = 3.4e6 operations, which is acceptable.
And the memory: about 10^5 nodes in sets and maps, which is acceptable.
We output the code without comments.
However, note: the problem says "code without comments", so we remove all comments.
Final code:
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
set<long long> ticketSet;
map<long long, string> ticketToOwner;
set<long long> globalWinningTickets;
map<string, vector<long long>> employeeTickets;
for (int i = 0; i < N; i++) {
string emp;
long long x;
cin >> emp >> x;
ticketSet.insert(x);
ticketToOwner[x] = emp;
employeeTickets[emp].push_back(x);
}
int Q;
cin >> Q;
while (Q--) {
int type;
cin >> type;
if (type == 1) {
long long x;
cin >> x;
auto it = ticketSet.lower_bound(x);
if (it == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[*it] << '\n';
globalWinningTickets.insert(*it);
}
} else if (type == 2) {
string y;
cin >> y;
if (employeeTickets.find(y) == employeeTickets.end()) {
cout << "ERROR\n";
} else {
const vector<long long>& tickets = employeeTickets[y];
vector<long long> wins;
for (long long t : tickets) {
if (globalWinningTickets.find(t) != globalWinningTickets.end()) {
wins.push_back(t);
}
}
for (int i = 0; i < wins.size(); i++) {
if (i > 0) cout << ' ';
cout << wins[i];
}
cout << '\n';
}
} else if (type == 3) {
long long x;
cin >> x;
if (ticketSet.find(x) == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[x] << '\n';
globalWinningTickets.insert(x);
}
}
}
return 0;
}
We run it with the sample and hope it passes.
Note: the problem says "memory less than 64MB" and "time less than 200ms". We hope so.
Let me test with a worst-case: 10^5 tickets and 10^5 queries.
Worst-case: all tickets are distinct and belong to distinct employees? Then employeeTickets has 10^5 entries, each vector has size 1. Then for type2: we have at most 100 type2 queries, each takes O(1) to traverse the vector. The type1 and type3: each O(log n). So total time O((10^5)*log(10^5)) which is about 1.7e6 operations, which is acceptable.
Memory: about 10^5 * (size of a node in set: 3 pointers + value: 8 bytes for long long -> 24+8=32 bytes per node? so 3.2e6 bytes for the set, and the map: 10^5 * (8+ say 9 for the string) -> but the string is stored per ticket? and we have 10^5 tickets -> 10^5 * (8+9) = 1.7e6 bytes? Then the employeeTickets: 10^5 * (size of string as key: 9 bytes? and vector: 24 bytes per vector + 8 bytes for the long long) -> 10^5 * (9 + 24 + 8) = 4.1e6 bytes. Total about 10 MB? So 64 MB is safe.
We are ready.
However, note: the problem says the employee ID is a string of the form "PATxxxxxx", which is 9 characters. But in C++ the string also stores the length and may have a small overhead. But 10^5 strings: 10^5 * (9+some overhead) is acceptable.
We output the code as above.
But note: the problem says "code without comments", so we have removed comments.
We hope it passes.
If there is an issue: the problem says "the same ticket can win multiple times", but we are only storing it once in the globalWinningTickets set. That is acceptable because we only need to know that it has won at least once.
And for type2, we output the ticket number once per distinct winning ticket (and in the order of input) -> that matches.
We are done.
Let me check the sample again: for the employee PAT000001, we output "1 2" at the end. But note: the ticket 1 was won twice? But we output it only once. The problem says "output all winning ticket numbers" meaning each distinct winning ticket? Yes.
So the code is correct.
We output the code in markdown.</think>### C++ Solution for Lucky Draw Problem
The solution efficiently handles the three types of actions (queries) by utilizing sets and maps for quick lookups and maintaining the order of tickets for each employee. The approach ensures optimal performance within the constraints.
#### Approach
1. **Data Structures**:
- **`ticketSet`**: A sorted set of all ticket numbers for efficient range queries (lower_bound).
- **`ticketToOwner`**: A map linking each ticket number to its owner's employee ID.
- **`globalWinningTickets`**: A set to track tickets that have won at least once.
- **`employeeTickets`**: A map associating each employee ID with their list of tickets (in input order).
2. **Processing Queries**:
- **Type 1 (1 x)**: Find the smallest ticket number ≥ x using `lower_bound`. Output the owner or "ERROR" if not found. Mark the ticket as won.
- **Type 2 (2 y)**: Output all winning tickets for employee y in input order. If the employee doesn't exist, output "ERROR". If no winning tickets, output an empty line.
- **Type 3 (3 x)**: Output the owner of ticket x or "ERROR" if not found. Mark the ticket as won.
#### Solution Code
```cpp
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
set<long long> ticketSet;
map<long long, string> ticketToOwner;
set<long long> globalWinningTickets;
map<string, vector<long long>> employeeTickets;
for (int i = 0; i < N; i++) {
string emp;
long long x;
cin >> emp >> x;
ticketSet.insert(x);
ticketToOwner[x] = emp;
employeeTickets[emp].push_back(x);
}
int Q;
cin >> Q;
while (Q--) {
int type;
cin >> type;
if (type == 1) {
long long x;
cin >> x;
auto it = ticketSet.lower_bound(x);
if (it == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[*it] << '\n';
globalWinningTickets.insert(*it);
}
} else if (type == 2) {
string y;
cin >> y;
if (employeeTickets.find(y) == employeeTickets.end()) {
cout << "ERROR\n";
} else {
const vector<long long>& tickets = employeeTickets[y];
vector<long long> wins;
for (long long t : tickets) {
if (globalWinningTickets.find(t) != globalWinningTickets.end()) {
wins.push_back(t);
}
}
for (int i = 0; i < wins.size(); i++) {
if (i > 0) cout << ' ';
cout << wins[i];
}
cout << '\n';
}
} else if (type == 3) {
long long x;
cin >> x;
if (ticketSet.find(x) == ticketSet.end()) {
cout << "ERROR\n";
} else {
cout << ticketToOwner[x] << '\n';
globalWinningTickets.insert(x);
}
}
}
return 0;
}
```
#### Explanation
- **Initialization**: The code reads all tickets, storing each ticket in `ticketSet`, mapping each ticket to its owner in `ticketToOwner`, and grouping tickets by employee in `employeeTickets`.
- **Query Processing**:
- **Type 1 (1 x)**: Uses `lower_bound` to find the smallest ticket ≥ x. If found, outputs the owner and marks the ticket as won.
- **Type 2 (2 y)**: Checks if the employee exists. If so, collects all winning tickets in input order and outputs them space-separated (or an empty line if none).
- **Type 3 (3 x)**: Checks if the ticket exists. If so, outputs the owner and marks the ticket as won.
- **Efficiency**: The use of sets and maps ensures O(log N) per query, making the solution efficient for large inputs (N, Q ≤ 10^5).
This approach efficiently handles all query types while maintaining optimal performance and memory usage.
---
**