Let's do a dry run first to observe the behavior of the sequence. Let $$$a = [1, 2, 0, 2, 2]$$$. We observe that the sequence $$$s$$$ is $$$[1, 2, 0, 2, 2, 3, 1, 4, 0, 5, 2, 3, 1, 4, 0, 5, 2, ...]$$$. We observe that the sequence is periodic from $$$s_{n+1}$$$ onwards with a period of $$$n + 1$$$. We also observe that the periodic part from $$$s_{n+1}$$$ to $$$s_{2n + 1}$$$ is a permutation of integers $$$0, 1, 2, ..., n$$$ (in this case, $$$3, 1, 4, 0, 5, 2$$$). Here's a way to prove it.
We know that all elements in the sequence are bounded by $$$n$$$ because the first $$$n$$$ elements indeed satisfy according to the problem constraints, and the mex of any $$$n$$$ non-negative integers can be at most $$$n$$$. Obviously, all elements in the sequence are non-negative.
Finally, we have to prove that all elements in $$$s_{n+1}, s_{n+2}, ..., s_{2n+1}$$$ are distinct.
For the sake of contradiction, assume two indices $$$i$$$ and $$$j$$$ exist such that $$$n + 1 \leq i \lt j \leq 2n + 1$$$ and $$$s_i$$$ = $$$s_j$$$. Now, $$$s_j = \operatorname{mex}(s_{j-1}, s_{j-2}, ..., s_{j-n})$$$. Now, $$$s_i$$$ lies in $$$s_{j-1}, s_{j-2}, ..., s_{j-n}$$$ because $$$j \leq i + n$$$ however $$$s_i$$$ = $$$s_j$$$ and since $$$s_j$$$ is the mex of integers containing $$$s_i$$$, we get a contradiction. Hence, all integers in $$$s_{n+1}, s_{n+2}, ..., s_{2n + 1}$$$ are distinct and between $$$0$$$ and $$$n$$$ inclusive. Hence, all elements from $$$s_{n+1}$$$ and $$$s_{2n+1}$$$ form a permutation of $$$0, 1, 2, ..., n$$$. Now we have to prove that the sequence is periodic from term $$$n+1$$$ onwards with a period of $$$n+1$$$. This means for all $$$i \geq 2n + 2$$$, $$$s_i$$$ = $$$s_{i-(n+1)}$$$. We know that $$$s_{2n+2} = \operatorname{mex}(s_{2n+1}, s_{2n}, ..., s_{n+2})$$$. We know that all these $$$n$$$ integers are distinct and do not contain $$$s_{n+1}$$$. Hence, the mex is $$$s_{n+1}$$$ and $$$s_{2n+2}$$$ = $$$s_{n+1}$$$ Hence, all integers in $$$s_{n+2}, s_{n+3}, ..., s_{2n+2}$$$ are distinct because $$$s_{n+1}, s_{n+2}, ..., s_{2n+1}$$$ are distinct. Hence, by induction, it can be proven that any $$$n+1$$$ consecutive terms are distinct. This can also prove that any pair of elements from whose lower term starts from $$$n+1$$$ onwards that differ by $$$n+1$$$ are equal. Hence, the sequence is periodic from term $$$n+1$$$ onwards. Now, we have to calculate $$$s_{n+1}, s_{n+2}, ..., s_{2n+1}$$$. A brute force approach — calculating the mex of each element manually by taking the last $$$n$$$ elements takes $$$O(n)$$$ per computation for overall $$$O(n^2)$$$ time which is too slow. The problem now becomes similar to the sliding window mex problem where the array size is $$$2n + 1$$$ and the window size is $$$n$$$. We'll use a set called missing to keep track of the missing elements in the current sliding window. We'll erase the possibly missing element that comes inside the window. What about the one that leaves the window? We'll need to use a frequency array for this. Let $$$freq_i$$$ be the frequency of element $$$i$$$ in the current window for $$$0 \leq i \leq n$$$. Now, we'll increment the frequency of the element coming inside the window and decrement the frequency of the element leaving the window. If the frequency of the element leaving the window becomes $$$0$$$, that element is no longer present in the window, and we can insert it back into the missing elements set. Each time, we have the current element = smallest missing element in the set, that is *missing.begin(); because sets are always sorted. Hence, we can calculate $$$s_{n+1}, s_{n+2}, ..., s_{2n+1}$$$ in $$$O(\log n)$$$ time, for an overall time complexity of $$$O(n \log n)$$$ Denote $$$perm_i$$$ = $$$s_{n+i}$$$ for all $$$1 \leq i \leq n + 1$$$. Now, what is the value of $$$s_k$$$ for some value of $$$k$$$? If $$$k \leq n$$$, the answer is simply $$$a_k$$$. Else, we know that the index of the answer in the periodic part is $$$(k \mod {n + 1}) + 1$$$. For example, if $$$k = n + 2$$$, the index will be $$$2$$$. This repeats every $$$n + 1$$$ terms. Hence, the answer is $$$perm_{(k\mod{n + 1}) + 1}$$$. Each query takes $$$O(1)$$$ time. Hence, the overall time complexity of the code will be $$$O(n \log n + q$$$).
Code#include <bits/stdc++.h>
using namespace std;
void solve() {
int n, q;
cin >> n >> q;
vector<int> a(n + 1);
for(int i = 1; i <= n; i++) cin >> a[i];
vector<int> freq(n + 1, 0);
set<int> missing;
for(int i = 1; i <= n; i++) freq[a[i]]++;
for(int i = 0; i <= n; i++) {
if(freq[i] == 0) missing.insert(i);
}
vector<int> perm(n + 2);
for(int i = 1; i <= n + 1; i++) {
perm[i] = *missing.begin();
missing.erase(perm[i]);
freq[perm[i]]++;
if(i <= n) {
freq[a[i]]--;
if(freq[a[i]] == 0) missing.insert(a[i]);
}
}
for(int i = 0; i < q; i++) {
long long k;
cin >> k;
if(k <= n) cout << a[k];
else {
int idx = (k % (n + 1)) + 1;
cout << perm[idx];
}
if(i == q - 1) cout << endl;
else cout << ' ';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while(t--) solve();
return 0;
}
If k>2N then its easy to solve it with a formula otherwise you can just bruteforce first 2N elements before the queries and output a[K]
How does your "easy" formula work, and how do you brute force efficiently (n=1e5)?
My solution is as follows: First observe that s_{i+1},...,s_{i+n} cannot be equal to s_{i}, and furthermore for i>n, we have s_{i} <= n, since it is the mex of n numbers. Hence for i>n, the sequence is periodic with period n+1, and s_{n+1},...,s_{2n+2} are a permutation of 0,...,n.
To find this permutation, we can use an std::set that stores the numbers from 0,...,n that do not occur in our 'current' window of n elements. we can find the MEX by doing *set.begin(), and update the set by adding numbers s_{i-n} to it if it is the last occurrence of s_{i-n} in the interval, and removing s_{i} from the set, since after the interval moves one place to the right it will contain s_{i}.
I am not sure if there is an easier way? what is your solution?
Use ordered set and binary search for the first value i such that order_of_key(i) doesnt equal i and then you know the mex is i. Now you continue this until all values from 0-N are filled then you will notice that the Mex will just increase by one each time
that sounds significantly more annoying to implement, and is slower (O(n log(n)^2) instead of O(n log(n))
I think you can optimize it and use dsu instead of ordered set where you draw an edge to the next element that didnt appear yet and once u add an element i just draw an edge between that and find(i+1).
This will be O(N*alpha(n))
You also need to delete numbers, I am not sure how DSU can handle that. Can you maybe implement it?
Technically, if you want a ""faster"" solution, you can use https://en.wikipedia.org/wiki/Van_Emde_Boas_tree . Then it is O(n loglog(n)) :)
Come on! Please give a code solution quickly. I'll only count that. Hopefully you give one in C++ so that I can understand your code since I don't do Python and other languages.
aight, calm down:
Following is my approach: Simply find the MEX of the initial array, and that will be the element at the (n)th index (0-based) , these elements keep repeating, therefore element at index k is the same as the element at index k%(n+1)
UPD : I assumed that the elements were distinct , my bad
that does not work if the elements a_1,...,a_n are not unique, i.e. a_i=a_j for i,j <= n.
Yes I assumed they were distinct, my bad
I have a solution that solves for arbitrarily large $$$A_i$$$, of course if $$$A_i$$$ is like $$$\le 10^{100}$$$ then we got to do bignum calculation and it would be really annoying. If $$$k \le n$$$ we simple output $$$A_n$$$. Otherwise, WLOG, supposed $$$A$$$ is sorted, then $$$S_{n + 1 + [0, A_1)}$$$ would be $$$[0, A_1)$$$, and $$$S_{n + [A_1, A_2 - 1)}$$$ would be $$$[A_1 + 1, A_2)$$$, and so on.
Also, you will lose generality because the sequence values depend on the last $$$n$$$ terms which may not necessarily be sorted. Thus, the WLOG part is also wrong according to me.
Oh sorry, I didn't read the statement carefully. It says $$$S_i$$$ is the MEX of last $$$n$$$ terms, not all the previous terms. Otherwise my solution would be correct. Sorry about that man. If so then we can just maintain a set to track the missing element from $$$0$$$ to $$$n - 1$$$, and compute the smallest one for each element from $$$n + 1$$$ to $$$2n$$$.
you are 12 years old ?!!!
More specifically, I was born on 17 February 2013.
Cool. keep going bro, please don't get distracted in future. Good luck!