[Codeforces 864D]Make a Permutation!

Posted NaVi_Awson

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codeforces 864D]Make a Permutation!相关的知识,希望对你有一定的参考价值。

Description

Ivan has an array consisting of n elements. Each of the elements is an integer from 1 to n.

Recently Ivan learned about permutations and their lexicographical order. Now he wants to change (replace) minimum number of elements in his array in such a way that his array becomes a permutation (i.e. each of the integers from 1 to n was encountered in his array exactly once). If there are multiple ways to do it he wants to find the lexicographically minimal permutation among them.

Thus minimizing the number of changes has the first priority, lexicographical minimizing has the second priority.

In order to determine which of the two permutations is lexicographically smaller, we compare their first elements. If they are equal — compare the second, and so on. If we have two permutations x and y, then x is lexicographically smaller if xi < yi, where i is the first index in which the permutations x and y differ.

Determine the array Ivan will obtain after performing all the changes.

Input

The first line contains an single integer n (2 ≤ n ≤ 200 000) — the number of elements in Ivan‘s array.

The second line contains a sequence of integers a1, a2, ..., an (1 ≤ ai ≤ n) — the description of Ivan‘s array.

Output

In the first line print q — the minimum number of elements that need to be changed in Ivan‘s array in order to make his array a permutation. In the second line, print the lexicographically minimal permutation which can be obtained from array with q changes.

Sample Input

4
3 2 2 3

Sample Output

2
1 2 4 3

HINT

In the first example Ivan needs to replace number three in position 1 with number one, and number two in position 3 with number four. Then he will get a permutation [1, 2, 4, 3] with only two changed numbers — this permutation is lexicographically minimal among all suitable.

题解

又掉进了题意的坑里...

一开始以为更换数字的代价是前后数字的差值...结果发现更换代价就是$1$...水得不能再水...

那显然最小代价就是把多余的数字变成没有的数字。

对于序列的字典序,也很简单,我们玩一个小贪心,显然数字越小要放越前面。我们将没有的数字从大到小压入栈中。

从$1$~$n$遍历序列,若扫到重复的元素,如果栈顶元素比它小,显然要替换。若比它大,我们选择跳过(虽然只能跳过一次,但先跳总比后跳好),记录一下,防止之后重复跳两次。

 1 //It is made by Awson on 2017.9.29
 2 #include <set>
 3 #include <map>
 4 #include <cmath>
 5 #include <ctime>
 6 #include <queue>
 7 #include <stack>
 8 #include <vector>
 9 #include <cstdio>
10 #include <string>
11 #include <cstring>
12 #include <cstdlib>
13 #include <iostream>
14 #include <algorithm>
15 #define LL long long
16 #define Max(a, b) ((a) > (b) ? (a) : (b))
17 #define Min(a, b) ((a) < (b) ? (a) : (b))
18 #define sqr(x) ((x)*(x))
19 #define lowbit(x) ((x)&(-(x)))
20 using namespace std;
21 const int N = 200000;
22 void read(int &x) {
23     char ch; bool flag = 0;
24     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == -)) || 1); ch = getchar());
25     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
26     x *= 1-2*flag;
27 }
28 
29 int n, a[N+5], cnt[N+5];
30 bool skip[N+5];
31 stack<int>S;
32 
33 void work() {
34     read(n);
35     for (int i = 1; i <= n; i++) {
36         read(a[i]);
37         cnt[a[i]]++;
38     }
39     for (int i = n; i >= 1; i--)
40         if (!cnt[i]) S.push(i);
41     printf("%d\n", S.size());
42     for (int i = 1; i <= n; i++) {
43         if (cnt[a[i]] > 1) {
44             if (skip[a[i]] || a[i] > S.top()) {
45                 cnt[a[i]]--;
46                 a[i] = S.top();
47                 S.pop();
48             }
49             else skip[a[i]] = 1;
50         }
51     }
52     for (int i = 1; i <= n; i++) printf("%d ", a[i]);
53 }
54 int main() {
55     work();
56     return 0;
57 }

 

以上是关于[Codeforces 864D]Make a Permutation!的主要内容,如果未能解决你的问题,请参考以下文章

Make Square CodeForces - 1028H (dp)

Codeforces Round #436 D. Make a Permutation!

codeforces 1560D. Make a Power of Two 模拟+暴力

Codeforces Round #436 (Div. 2), problem: (D) Make a Permutation!

Codeforces 1328F Make k Equal

Educational Codeforces Round 42 (Rated for Div. 2) C. Make a Square