[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

43 2 2 3

Sample Output

21 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 }
时间: 2024-11-07 01:48:15

[Codeforces 864D]Make a Permutation!的相关文章

【搜索】【并查集】Codeforces 691D Swaps in Permutation

题目链接: http://codeforces.com/problemset/problem/691/D 题目大意: 给一个1到N的排列,M个操作(1<=N,M<=106),每个操作可以交换X Y位置上的数字,求可以得到的最大字典序的数列. 题目思路: [搜索][并查集] 这题可以用搜索或者并查集写,都能过. 把位置分成若干块,每一块里面的位置都是可以被这一块里另一个位置经过若干次调换的(类似强连通,位置可达). 然后把每一块位置里的 位置按从小到大排序,位置上的值按从大到小排序,依次填入位置

Codeforces 691D. Swaps in Permutation

题目链接:http://codeforces.com/problemset/problem/691/D 题意: 给你一个含有 N 个不重复数的序列, 以及 M 对形如 (ai, bj) 的数, (ai ,bj) 代表着可以把第 ai 个数可以和第 bj 个数进行交换, 问如何交换才能使得变换后的字典序最大,每个变化可选可不选,也可选多次. 思路: 可以想到, 如果 a 可以和 b 换, b 可以和 c 换, 那么 a 就可以间接的和 c 换, 依次类推, 如果某些位置直接可以变换, 那么与这些位

codeforces 500B.New Year Permutation 解题报告

题目链接:http://codeforces.com/problemset/problem/500/B 题目意思:给出一个含有 n 个数的排列:p1, p2, ..., pn-1, pn.紧接着是一个 n * n 的矩阵A,当且仅当 Aij = 1 时,pi 与 pj 可以交换数值.现在问如何交换数值,使得最后得到的排列字典序最小. 比赛的时候不会做,看了Tutorial 1 的解法,觉得别人做得太巧妙了,出题者也出得很好 ^_^ 可以看这个:http://codeforces.com/blog

codeforces 691D Swaps in Permutation(并查集)

题意: 给你一个长度为n的数列,然后给你m组数, 表示这两个数可以交换 然后让你给出字典序最大的数列 思路: 用并查集,可交换的数都是成组的,把同一并查集中的数加在根节点的vector后, 在一个并查集中的数,从大到输出就好了 /* *********************************************** Author :devil ************************************************ */ #include <cstdio>

codeforces 622. Optimal Number Permutation 构造

题目链接 假设始终可以找到一种状态使得值为0, 那么两个1之间需要隔n-2个数, 两个2之间需要隔n-3个数, 两个3之间隔n-4个数. 我们发现两个三可以放到两个1之间, 同理两个5放到两个3之间....这样就构造好了. #include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmat

CodeForces 618B Guess the Permutation

只要找出当前没用过的数字中,大于或等于当前这一列的最大值就可以 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn=100; int n; int x[maxn][maxn]; int ans[maxn]; int flag[maxn]; int mai

Codeforces 553B Kyoya and Permutation

problem 题意 本题题意不太容易看懂.给定一个序列,我们可以把这个序列变成一些循环置换的和.然而这种置换的方法是不止一种的.我们定义一种standard cyclic representation,即每个循环置换中最大的数都在第一个.把得到的循环置换的括号去掉,我们可以得到一个新的序列.定义一个序列,使得它变成置换后再去掉括号得到的新序列和原序列相同,那么称这样的序列是稳定的.给定一个n(序列长度)和k,要求求出所有稳定序列按字典序排序后的第k大序列. 思路 首先我们可以证明,稳定序列是具

CodeForces 622D Optimal Number Permutation

是一个简单构造题. 请观察公式: 绝对值里面的就是 |di-(n-i)|,即di与(n-i)的差值的绝对值. 事实上,对于任何n,我们都可以构造出来每一个i的di与(n-i)的差值为0. 换句话说,就是这个最小值一定可以构造出来是0. 假设输入是6:那么可以这样构造:1 3 5 5 3 1 2 4 6 4 2 6 假设输入是7:那么可以这样构造:1 3 5 7 5 3 1 2 4 6 6 4 2 7 从上面就能看出怎么构造了,n最后放空缺的两个位置,剩下的从小到大一个一个放,奇数放左边构造,偶数

Codeforces 500B - New Year Permutation(最短路)

题意:给你一个序列    ,   给你一个mark 矩阵 , 如果mark[i][j] = 1,  则代表序列i    j  可以交换,需要求出交换之后字典序最小的序列 题解: floyd 处理一遍,然后靠前的优先选择最小的数  ,  然后没了 代码: #include<stdio.h> #include<string.h> #define N_node 305 int n, dis[N_node][N_node], value[N_node], dir[N_node], mark