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.
Before thinking about cost, check whether the range can be emptied at all. Since each move removes three equal values, both the number of s and the number of s must be divisible by .
If the range is possible, it takes exactly operations for length . Every operation costs at least , so is a hard lower bound.
An operation costs exactly iff among the chosen three equal elements, two are adjacent in the current array.
So the only thing that can force extra cost is having no adjacent equal elements at the start. In a binary array, that means the whole range is perfectly alternating.
Final rule: if counts are not divisible by , answer . Otherwise answer , plus only when the queried range is alternating. Prefix sums handle both counts and alternation.
Let the queried subarray have length .
First: When Is It Possible?
Every operation removes exactly three equal values. So the number of s and the number of s are independent constraints:
If either one fails, the answer is . No operation order can fix bad divisibility. Arithmetic is annoyingly undefeated.
Assume from now on that both counts are divisible by .
Lower Bound
Each operation removes elements, so we need exactly
operations.
For any chosen triple , the cost is
Both gaps are positive, so every operation costs at least . Therefore:
The whole problem is now: when can we make every operation cost exactly ?
Cost 1 Means Adjacent Equal Elements
A triple removal costs exactly when two of the three chosen equal elements are adjacent in the current array.
So if the array has an adjacent equal pair, say 00 or 11, we can use that pair plus one more equal value to perform a cost- removal.
Because that value's count is divisible by , having two copies means there is a third copy unless the range was impossible, which we already filtered out.
The Only Bad Shape Is Alternating
If a binary array has no adjacent equal pair, then it must be perfectly alternating:
or
In that shape, equal values are separated by at least one opposite value. The closest three equal elements have gaps and , so the first move costs at least . It can also cost exactly , by taking three consecutive occurrences of one value.
After removing those three equal elements, the other value gets glued together somewhere, so the remaining array now has adjacent equal elements. From then on, the lower bound is reachable.
So for a valid alternating range:
Why Non-Alternating Ranges Reach the Lower Bound
If the range is not alternating, it has at least one adjacent equal pair.
There is a useful run-based fact:
In any valid non-alternating binary array, we can remove some cost- triple so that the remaining array is either empty or still non-alternating.
Why? Look at runs of equal values. Since the array is non-alternating, some run has length at least . We remove two adjacent elements from such a run and choose the third equal element so that either:
If neither can be done, then every run must have length , which means the array was alternating in the first place. Contradiction.
So by induction, a valid non-alternating range can be fully deleted with cost per operation. Therefore:
Answering Queries
For each query :
Precompute:
and prefix sums of same. Then is alternating iff
So the logic is:
The preprocessing is and each query is , so each test case 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;
while (T--) {
int n, q;
cin >> n >> q;
vector<int> a(n + 1);
vector<int> prefOne(n + 1, 0), prefSame(n + 1, 0);
for (int i = 1; i <= n; i++) {
cin >> a[i];
prefOne[i] = prefOne[i - 1] + a[i];
}
for (int i = 1; i < n; i++) {
prefSame[i] = prefSame[i - 1] + (a[i] == a[i + 1]);
}
prefSame[n] = prefSame[n - 1];
while (q--) {
int l, r;
cin >> l >> r;
int len = r - l + 1;
int ones = prefOne[r] - prefOne[l - 1];
int zeros = len - ones;
if (ones % 3 != 0 || zeros % 3 != 0) {
cout << -1 << '\n';
continue;
}
int equalAdjacent = prefSame[r - 1] - prefSame[l - 1];
cout << len / 3 + (equalAdjacent == 0) << '\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;
while (T--) {
int n, q;
cin >> n >> q;
vector<int> a(n + 1);
vector<int> prefOne(n + 1, 0), prefSame(n + 1, 0);
for (int i = 1; i <= n; i++) {
cin >> a[i];
prefOne[i] = prefOne[i - 1] + a[i];
}
for (int i = 1; i < n; i++) {
prefSame[i] = prefSame[i - 1] + (a[i] == a[i + 1]);
}
prefSame[n] = prefSame[n - 1];
while (q--) {
int l, r;
cin >> l >> r;
int len = r - l + 1;
int ones = prefOne[r] - prefOne[l - 1];
int zeros = len - ones;
if (ones % 3 != 0 || zeros % 3 != 0) {
cout << -1 << '\n';
continue;
}
int equalAdjacent = prefSame[r - 1] - prefSame[l - 1];
cout << len / 3 + (equalAdjacent == 0) << '\n';
}
}
return 0;
}