Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Track the common prefix displacement . A robot starting at is at after moves.
Since changes by exactly each step, reaching displacement means every displacement was reached earlier too. Same idea on the negative side.
For one robot, you do not care about every spike. On the right, only the nearest spike matters; on the left, only the nearest spike matters. Farther spikes are slower to hit, so they can’t be the first killer.
For each robot , compute Then the robot dies when the displacement first reaches or first reaches .
Precompute firstRight[d] = first time the displacement becomes , and firstLeft[d] = first time it becomes . Then each robot contributes one death event at
Let be the displacement after the first instructions, where . Every robot receives the same commands, so a robot starting at position is at
after moves.
A robot dies if this equals some spike position , meaning
So the whole problem is about when the displacement first reaches certain values.
The important observation: the displacement changes by exactly or . Therefore, before the walk can reach displacement , it must have reached every positive displacement below it. Likewise, before reaching , it must have reached every negative displacement above it. No teleporting. Physics remains undefeated.
Now fix one robot at position .
For spikes to the right of the robot, where , the needed displacement is . Among all such spikes, the nearest one has the smallest required positive displacement. Any farther right spike needs an even larger positive displacement, and reaching that larger displacement would already have passed through the nearest spike’s displacement. So only the nearest spike to the right can be the first right-side killer.
Similarly, among spikes to the left, only the nearest spike to the left matters.
Define:
If no such spike exists on a side, that value is infinity.
The robot dies at the earlier of:
So we just need two pieces of preprocessing.
First, scan the instruction string and compute the prefix displacement. Store:
Only matters, because after unit moves the displacement magnitude cannot exceed .
Second, sort the spike positions. For each robot position , use binary search to find:
Then compute the robot’s death time:
If both are infinity, the robot never dies.
Create an array deadAt, where deadAt[i] counts how many robots die exactly after instruction . Finally, walk from to , subtract deadAt[i] from the alive count, and print the result.
Correctness proof
For any robot starting at , it is at after moves by definition of the common displacement. It dies exactly when for some spike , equivalently .
Consider spikes to the right of . Let the nearest right spike be at distance . Any other right spike has distance . Since the displacement starts at and changes by per move, reaching requires reaching earlier. Therefore no farther right spike can kill the robot before the nearest right spike. Thus the nearest right spike fully determines all possible first deaths caused by right-side spikes.
The same argument applies to the left side: if the nearest left spike is at distance , any farther left spike requires displacement with , and reaching requires reaching first.
Therefore each robot’s death time is exactly the minimum of the first time the displacement reaches and the first time it reaches . The algorithm computes these first-reaching times directly from the instruction prefixes and computes from the sorted spikes. Hence every robot is assigned its exact death time.
The final output subtracts exactly the robots whose death time equals each prefix index, so after every instruction it prints exactly the number of robots still alive.
Edge cases
If a robot has no spike on one side, that side contributes infinity. If the nearest spike is farther than , it also cannot be reached. Initial positions never overlap by statement guarantee, so no robot is dead at time .
Complexity
Sorting spikes costs . Each robot does one binary search, so . Scanning the instruction string is .
Total complexity per test case:
Memory usage is .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
const int INF = 1e9;
while (T--) {
int n, m, k;
cin >> n >> m >> k;
vector<ll> a(n), b(m);
for (ll &x : a) cin >> x;
for (ll &x : b) cin >> x;
string s;
cin >> s;
sort(b.begin(), b.end());
vector<int> firstR(k + 1, INF), firstL(k + 1, INF);
int pos = 0;
for (int i = 1; i <= k; ++i) {
pos += (s[i - 1] == 'R' ? 1 : -1);
if (pos > 0 && firstR[pos] == INF) firstR[pos] = i;
if (pos < 0 && firstL[-pos] == INF) firstL[-pos] = i;
}
vector<int> deadAt(k + 1, 0);
for (ll x : a) {
int die = INF;
auto it = upper_bound(b.begin(), b.end(), x);
if (it != b.end()) {
ll dist = *it - x;
if (dist <= k) die = min(die, firstR[(int)dist]);
}
if (it != b.begin()) {
--it;
ll dist = x - *it;
if (dist <= k) die = min(die, firstL[(int)dist]);
}
if (die <= k) ++deadAt[die];
}
int alive = n;
for (int i = 1; i <= k; ++i) {
alive -= deadAt[i];
cout << alive << ' ';
}
cout << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int T;
cin >> T;
const int INF = 1e9;
while (T--) {
int n, m, k;
cin >> n >> m >> k;
vector<ll> a(n), b(m);
for (ll &x : a) cin >> x;
for (ll &x : b) cin >> x;
string s;
cin >> s;
sort(b.begin(), b.end());
vector<int> firstR(k + 1, INF), firstL(k + 1, INF);
int pos = 0;
for (int i = 1; i <= k; ++i) {
pos += (s[i - 1] == 'R' ? 1 : -1);
if (pos > 0 && firstR[pos] == INF) firstR[pos] = i;
if (pos < 0 && firstL[-pos] == INF) firstL[-pos] = i;
}
vector<int> deadAt(k + 1, 0);
for (ll x : a) {
int die = INF;
auto it = upper_bound(b.begin(), b.end(), x);
if (it != b.end()) {
ll dist = *it - x;
if (dist <= k) die = min(die, firstR[(int)dist]);
}
if (it != b.begin()) {
--it;
ll dist = x - *it;
if (dist <= k) die = min(die, firstL[(int)dist]);
}
if (die <= k) ++deadAt[die];
}
int alive = n;
for (int i = 1; i <= k; ++i) {
alive -= deadAt[i];
cout << alive << ' ';
}
cout << '\n';
}
return 0;
}