C. MEX Repetition
You are given an array $a_1,a_2,\ldots, a_n$ of pairwise distinct integers from $0$ to $n$. Consider the following operation:
- consecutively for each $i$ from $1$ to $n$ in this order, replace $a_i$ with $\operatorname{MEX}(a_1, a_2, \ldots, a_n)$.
Here $\operatorname{MEX}$ of a collection of integers $c_1, c_2, \ldots, c_m$ is defined as the smallest non-negative integer $x$ which does not occur in the collection $c$. For example, $\operatorname{MEX}(0, 2, 2, 1, 4) = 3$ and $\operatorname{MEX}(1, 2) = 0$.
Print the array after applying $k$ such operations.
Input
Each test contains multiple test cases. The first line contains the number of test cases $t$ ($1 \le t \le 10^5$). The description of the test cases follows.
The first line of each test case contains two integers $n$ and $k$ ($1\le n\le 10^5$, $1\le k\le 10^9$).
The second line contains $n$ pairwise distinct integers $a_1,a_2,\ldots, a_n$ ($0\le a_i\le n$) representing the elements of the array before applying the operations.
It is guaranteed that the sum of $n$ over all test cases does not exceed $10^5$.
Output
For each test case, print all $n$ elements of the array after applying $k$ operations.
Example
input
5 1 2 1 3 1 0 1 3 2 2 0 2 5 5 1 2 3 4 5 10 100 5 3 0 4 2 1 6 9 10 8
output
1 2 0 1 2 1 2 3 4 5 0 7 5 3 0 4 2 1 6 9 10
Note
In the first test case, here is the entire process:
- On the first operation, the array changes from $[1]$ to $[0]$, since $\operatorname{MEX}(1) = 0$.
- On the second operation, the array changes from $[0]$ to $[1]$, since $\operatorname{MEX}(0) = 1$.
Thus, the array becomes $[1]$ after two operations.
In the second test case, the array changes as follows during one operation: $[{\mkern3mu\underline{\mkern-3mu {\bf 0}\mkern-3mu}\mkern3mu}, 1, 3] \rightarrow [2, {\mkern3mu\underline{\mkern-3mu {\bf 1}\mkern-3mu}\mkern3mu}, 3] \rightarrow [2, 0, {\mkern3mu\underline{\mkern-3mu {\bf 3}\mkern-3mu}\mkern3mu}] \rightarrow [2, 0, 1]$.
In the third test case, the array changes as follows during one operation: $[{\mkern3mu\underline{\mkern-3mu {\bf 0}\mkern-3mu}\mkern3mu}, 2] \rightarrow [1, {\mkern3mu\underline{\mkern-3mu {\bf 2}\mkern-3mu}\mkern3mu}] \rightarrow [1, 0]$. And during the second operation: $[{\mkern3mu\underline{\mkern-3mu {\bf 1}\mkern-3mu}\mkern3mu}, 0] \rightarrow [2, {\mkern3mu\underline{\mkern-3mu {\bf 0}\mkern-3mu}\mkern3mu}] \rightarrow [2, 1]$.
解题思路
看到$k$这么大肯定是有循环节的。在原有数组$a$的情况下令$a_{n+1} = \operatorname{MEX}(a_1, \ldots, a_n)$,此时长度为$n+1$的数组$a$就是$0 \sim n$的一个排列。每轮中的$a_i = \operatorname{MEX}(a_1, \ldots, a_n)$其实就是交换$a_i$和$a_{n+1}$的值,因为在交换后还是$0 \sim n$的一个排列,因此$\operatorname{MEX}(a_1, \ldots, a_n)$还是等于$a_{n+1}$。
所以在一轮操作之后,数组从$[a_1, a_2, \ldots, a_{n+1}]$变到$[a_{n+1}, a_1, a_2, \ldots, a_n]$,本质就是循环右移一个单位。所以最终答案就是将原数组补充$a_{n+1} = \operatorname{MEX}(a_1, \ldots, a_n)$后循环右移$k \bmod (n+1)$个单位。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 1e5 + 10; 7 8 int a[N]; 9 bool vis[N]; 10 11 void solve() { 12 int n, m; 13 scanf("%d %d", &n, &m); 14 memset(vis, 0, n + 10); 15 for (int i = 0; i < n; i++) { 16 scanf("%d", a + i); 17 vis[a[i]] = true; 18 } 19 for (int i = 0; i <= n; i++) { 20 if (!vis[i]) { 21 a[n++] = i; 22 break; 23 } 24 } 25 m %= n; 26 for (int i = 0, j = (n - m) % n; i < n - 1; i++) { 27 printf("%d ", a[j]); 28 if (++j == n) j = 0; 29 } 30 printf("\n"); 31 } 32 33 int main() { 34 int t; 35 scanf("%d", &t); 36 while (t--) { 37 solve(); 38 } 39 40 return 0; 41 }
参考资料
Pinely Round 2 Editorial:https://codeforces.com/blog/entry/119902
标签:10,3mu,ldots,mkern,Repetition,MEX,mkern3mu From: https://www.cnblogs.com/onlyblues/p/17669544.html