B - ロボットの宝集め / Robot's Treasure Collection 解説 by admin
gemini-3-flash-thinkingOverview
This is a simulation problem where you operate a robot according to an instruction sequence \(S\) of length \(Q\) to collect treasures placed in \(N\) rooms. You process a total of \(M\) operations, which consist of queries that rewrite part of the instruction sequence and queries that ask for the total score when executing the current instruction sequence.
Key Insight
The most important point of this problem is the constraint: “If the number of operation 2’s is \(K\), then \(KQ \leq 2 \times 10^7\).”
Normally, if both the instruction sequence length \(Q\) and the number of operations \(M\) are around \(10^5\), performing an \(O(Q)\) simulation for each query would result in a worst-case complexity of \(O(MQ) \approx 10^{10}\), which would not fit within the time limit. However, in this problem, the “total number of simulation steps across all queries” is kept sufficiently small, so naively simulating each time operation 2 is called is an effective approach.
In the simulation, the following points require attention:
- Duplicate treasure collection detection: Collecting treasure from the same room more than once does not add to the score.
- Maximum score value: The treasure value \(A_i\) can be up to \(10^9\), and the total score may exceed \(2^{31}-1\), so a 64-bit integer type (long long in C++) must be used.
- Efficient state reset: For each query, you need to reset the information about “which rooms’ treasures have been collected.” If you initialize a vector<bool> in \(O(N)\) each time, the per-query complexity becomes \(O(Q + N)\), and even with the \(KQ\) constraint, \(KN\) could become large and cause TLE (Time Limit Exceeded).
Algorithm
For each operation 2, perform the simulation with the following steps:
- Initialization:
- Set the robot’s current room to
1. - Set the current score to
0.
- Set the robot’s current room to
- Instruction execution:
Check each character of the instruction sequence \(S\) from the beginning and perform the following:
L: If the room number is greater than \(1\), decrease it by \(1\).R: If the room number is less than \(N\), increase it by \(1\).P: If the treasure in the current room has not been collected, add the value \(A_i\) to the score and mark it as “collected.”B: Change the room number to \(1\).
- Duplicate collection management (optimization):
For the “collected” check, prepare an array
last_collected[room_id]that records “the query number when the treasure in that room was last collected.”- If
last_collected[current_room] != query_count, then it is judged as uncollected. - Upon collection, update
last_collected[current_room] = query_count. This eliminates the need to fill all elements of the array with \(0\) for initialization at each query.
- If
Complexity
- Time complexity: \(O(M + KQ)\)
- Update operations (operation 1) are \(O(1)\).
- Query operations (operation 2) take \(O(Q)\) each.
- Since \(KQ \leq 2 \times 10^7\) by the constraint, this fits well within the time limit.
- Space complexity: \(O(N + Q)\)
- The treasure values \(A\) and the collection check array
last_collecteduse \(O(N)\), and the instruction sequence \(S\) uses \(O(Q)\) memory.
- The treasure values \(A\) and the collection check array
Implementation Notes
Fast I/O: Since \(M\) and \(Q\) can be large, in C++ it is recommended to use
cin.tie(NULL); ios_base::sync_with_stdio(false);to speed up standard I/O.1-indexed vs 0-indexed: Room numbers and character positions in the problem statement start from \(1\), but arrays and strings in programs typically start from \(0\), so be careful with index handling.
Source Code
#include <iostream>
#include <vector>
#include <string>
using namespace std;
/**
* Problem: Robot Treasure Collection
* This problem asks us to simulate a robot's movement and treasure collection
* along a line of rooms based on a sequence of commands. There are updates
* to the command sequence and queries to calculate the total score.
*
* Given the constraint KQ <= 2 * 10^7 (where K is the number of queries and
* Q is the command sequence length), a direct simulation for each query
* is efficient enough.
*/
int main() {
// Optimize standard I/O performance
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N, Q, M;
// Read the number of rooms N, length of command sequence Q, and number of operations M
if (!(cin >> N >> Q >> M)) return 0;
// Read the treasure values for each room (1 to N)
// Using long long for treasure values as they can be up to 10^9
vector<long long> A(N + 1);
for (int i = 1; i <= N; ++i) {
cin >> A[i];
}
// Read the initial command sequence S
string S;
cin >> S;
// last_collected[i] stores the ID of the last query in which the treasure
// in room i was collected. This allows us to track collected treasures
// for each query independently without clearing a boolean array in O(N).
vector<int> last_collected(N + 1, 0);
int query_count = 0;
// Process each of the M operations
for (int i = 0; i < M; ++i) {
int op_type;
cin >> op_type;
if (op_type == 1) {
// Update operation: change p-th command to character c
int p;
char c;
cin >> p >> c;
// p is 1-indexed in the problem, convert to 0-indexed for the string
S[p - 1] = c;
} else if (op_type == 2) {
// Query operation: simulate the robot's execution of the command sequence S
query_count++;
long long current_score = 0;
int current_room = 1;
// Iterate through the command sequence and update the robot's state
for (char cmd : S) {
if (cmd == 'L') {
// Move left if possible
if (current_room > 1) current_room--;
} else if (cmd == 'R') {
// Move right if possible
if (current_room < N) current_room++;
} else if (cmd == 'P') {
// Collect treasure if it hasn't been collected in this specific query
if (last_collected[current_room] != query_count) {
current_score += A[current_room];
last_collected[current_room] = query_count;
}
} else if (cmd == 'B') {
// Move directly back to room 1
current_room = 1;
}
}
// Output the final score for the current simulation
cout << current_score << "\n";
}
}
return 0;
}
This editorial was generated by gemini-3-flash-thinking.
投稿日時:
最終更新: