I try to solve this question: B. Informatics in MAC at Codeforces To solve it, I think I need to calculate the prefix and suffix array of MEX. I made observation that making only 1 subsegment will give good answer. We are required to make at least 2, but we know that MEX of every segment must be equal, so making segments as large as possible is optimal.
Due to this, we just can calculate prefix and suffix arrays of MEX, and if at some index i
they are equal, we have the answer.
The problem is: how to calculate it efficiently? That my current code:
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> a(n);
int a_max = 0;
for (int i = 0; i < n; ++i) {
cin >> a[i];
a_max = max(a_max, a[i]);
}
vector<int> mex_prefix(n);
vector<int> mex_suffix(n);
mex_prefix[0] = a[0] > 0 ? 0 : 1;
mex_suffix[n - 1] = a[n - 1] > 0 ? 0 : 1;
// Problematic part starts here
set<int> s1{ a[0] };
set<int> s2{ a[n - 1] };
for (int i = 1, j = n - 2; i < n && j >= 0; ++i, --j) {
s1.insert(a[i]);
s2.insert(a[j]);
for (int val = 0; val <= a_max + 1; ++val) {
if (s1.find(val) == s1.end()) {
mex_prefix[i] = max(mex_prefix[i - 1], val);
break;
}
}
for (int val = 0; val <= a_max + 1; ++val) {
if (s2.find(val) == s2.end()) {
mex_suffix[j] = max(mex_suffix[j + 1], val);
break;
}
}
}
// End
bool valid = false;
int i = 0;
for (; i < n - 1; ++i) {
if (mex_prefix[i] == mex_suffix[i + 1]) {
valid = true;
break;
}
}
if (!valid) {
cout << -1 << '\n';
}
else {
cout << 2 << '\n';
cout << 1 << ' ' << i + 1 << '\n';
cout << i + 2 << ' ' << n << '\n';
}
}
}
I will discuss it for prefix array, because building suffix array is analogous.
We set 0-th
index of prefix array to valid MEX, and then we iterate through a
array, while adding elements to set s1
. At every a[i]
, we check whether it will increase the MEX
on 0..i
prefix. How? We iterate through all possible values (0 to max(a) + 1
) and check if the current value was present in a
suffix up to i
. If it wasn't, then it can be MEX only if it's greater than MEX suffix up to previous index i - 1
. If we find that value, then it's lowest value not present in suffix a[0..i]
.
The complexity of this it too big. It's like O(n * max(a) * logN)
(due to using set
to check if element exists in a
till index i
, and inserting elements to the set), which can result in more than 10^10
operations. How can we speed it up?