Paprika and Permutation
传送门
Paprika loves permutations. She has an array a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an. She wants to make the array a permutation of integers 1 1 1 to n n n.
In order to achieve this goal, she can perform operations on the array. In each operation she can choose two integers i i i ( 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n) and x x x ( x > 0 x > 0 x>0), then perform a i : = a i m o d x a_i := a_i \bmod x ai:=aimodx (that is, replace a i a_i ai by the remainder of a i a_i ai divided by x x x). In different operations, the chosen i i i and x x x can be different.
Determine the minimum number of operations needed to make the array a permutation of integers 1 1 1 to n n n. If it is impossible, output − 1 -1 −1.
A permutation is an array consisting of n n n distinct integers from 1 1 1 to n n n in arbitrary order. For example, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] is a permutation, but [ 1 , 2 , 2 ] [1,2,2] [1,2,2] is not a permutation ( 2 2 2 appears twice in the array) and [ 1 , 3 , 4 ] [1,3,4] [1,3,4] is also not a permutation ( n = 3 n=3 n=3 but there is 4 4 4 in the array).
Input
Each test contains multiple test cases. The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104) — the number of test cases. Description of the test cases follows.
The first line of each test case contains an integer n n n ( 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1≤n≤105).
The second line of each test case contains n n n integers a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an. ( 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109).
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105.
Output
For each test case, output the minimum number of operations needed to make the array a permutation of integers 1 1 1 to n n n, or − 1 -1 −1 if it is impossible.
Example
input
4
2
1 7
3
1 5 4
4
12345678 87654321 20211218 23571113
9
1 2 3 4 18 19 5 6 7
output
1
-1
4
2
Note
For the first test, the only possible sequence of operations which minimizes the number of operations is:
- Choose i = 2 i=2 i=2, x = 5 x=5 x=5. Perform a 2 : = a 2 m o d 5 = 2 a_2 := a_2 \bmod 5 = 2 a2:=a2mod5=2.
For the second test, it is impossible to obtain a permutation of integers from 1 1 1 to n n n.
题目翻译
红辣椒喜欢排列组合。她有一个数组 a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an 。她想把数组变成一个从 1 1 1 到 n n n 的整数的置换。
为了实现这个目标,她可以对数组进行运算。在每次操作中,她可以选择两个整数 i i i ( 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n )和 x x x ( x > 0 x > 0 x>0 ),然后执行 a i : = a i m o d x a_i := a_i \bmod x ai:=aimodx (即用 a i a_i ai 除以 x x x 的余数替换 a i a_i ai )。在不同的操作中,所选的 i i i 和 x x x 可能不同。可能会不同。
确定使数组成为整数 1 1 1 至 n n n 的排列所需的最少运算次数。如果不可能,则输出 − 1 -1 −1 .
排列是由 n n n 个不同的整数组成的数组,这些整数从 1 1 1 到 n n n 按任意顺序排列。例如, [ 2 , 3 , 1 , 5 , 4 ] [2,3,1,5,4] [2,3,1,5,4] 是一个排列,但 [ 1 , 2 , 2 ] [1,2,2] [1,2,2] 不是一个排列( 2 2 2 在数组中出现了两次), [ 1 , 3 , 4 ] [1,3,4] [1,3,4] 也不是一个排列( n = 3 n=3 n=3 ,但数组中有 4 4 4 )。
输入
每个测试包含多个测试用例。第一行包含一个整数 t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104 ) - 测试用例数。测试用例说明如下。
每个测试用例的第一行都包含一个整数 n n n ( 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1≤n≤105 )。
每个测试用例的第二行包含 n n n 个整数 a 1 , a 2 , … , a n a_1, a_2, \dots, a_n a1,a2,…,an .( 1 ≤ a i ≤ 1 0 9 1 \le a_i \le 10^9 1≤ai≤109 ).
保证所有测试用例中 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105 。
输出
对于每个测试用例,输出使数组成为从 1 1 1 到 n n n 的整数排列所需的最少操作数,如果不可能,则输出 − 1 -1 −1 。
提示
对于第一个测试,唯一可能的操作序列是将操作次数减至最少:
- 选择 i = 2 i=2 i=2 , x = 5 x=5 x=5 。执行 a 2 : = a 2 m o d 5 = 2 a_2 := a_2 \bmod 5 = 2 a2:=a2mod5=2 。
对于第二个测试,不可能得到从 1 1 1 到 n n n 的整数排列。
注明
以上来自
C
o
d
e
F
o
r
c
e
s
,翻译来源:
D
e
e
p
L
。
以上来自 CodeForces,翻译来源:DeepL。
以上来自CodeForces,翻译来源:DeepL。
洛谷 MarkDown 格式还是太难绷了。
解题思路
题目要求将原序列通过对一个数取模或不取模,使得原序列中的元素可以组成 1 ∼ n 1 \sim n 1∼n 的序列,要求最小的取模次数(如果无解,则输出 − 1 -1 −1)。
为了取模次数最小,要注意:
- 对于一个数最多取一次模(显然);
- 对于值在 [ 1 , n ] [1,n] [1,n] 范围内的且之前没有相同值的元素不做修改。
然后考虑取模操作。先给出结论:一个正整数 x x x 与一个小于等于 x x x 的正整数 y y y 相除后余数一定在 [ 0 , ⌊ n − 1 2 ⌋ ] [0,\lfloor\frac{n-1}{2}\rfloor] [0,⌊2n−1⌋] 区间内。证明如下:
- 对于“ 0 0 0”,就是 x x x 整除 y y y 的情况;
- 对于“ ⌊ n − 1 2 ⌋ \lfloor\frac{n-1}{2}\rfloor ⌊2n−1⌋”,显然为了余数尽可能大,则除数要尽可能大,当除数为 ⌈ n + 1 2 ⌉ \lceil\frac{n+1}{2}\rceil ⌈2n+1⌉ 时,余数最大。
那么解法显然就是先在输入序列元素时记录下值在区间 [ 1 , n ] [1,n] [1,n] 内且之前没有相同值的元素,对于它们后期不做修改。再将序列从小到大排序,若元素 a i a_i ai 满足 a i < ⌊ i 2 ⌋ a_i<\lfloor\frac{i}{2}\rfloor ai<⌊2i⌋ 则一定无解,直接输出 − 1 -1 −1 即可。
AC Code
#include<bits/stdc++.h>
using namespace std;
char buf[1048576], *p1, *p2;
template<typename T>inline void Super_Quick_Read(T &x) {
bool f = 1;
x = 0;
char ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
while (ch < '0' || ch > '9') {
if (ch == '-') f = !f;
ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
}
while (ch >= '0' && ch <= '9')x = (x << 1) + (x << 3) + (ch ^ 48), ch = (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 20, stdin), p1 == p2) ? 0 : *p1++);
x = (f ? x : -x);
return;
}
template<typename T>inline void Quick_Write(T x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) Quick_Write(x / 10);
putchar(x % 10 + '0');
return;
}
int n, a[200005];
bool Vis[200005];
int T[200005], Top;
int Answer;
signed main() {
int t;
Super_Quick_Read(t);
bool flag;
while (t--) {
for (register int i = 1; i <= n; ++i) T[i] = Vis[i] = 0;
Top = 0, Answer = 0, flag = 0, Super_Quick_Read(n);
for (register int i = 1; i <= n; ++i) Super_Quick_Read(a[i]);
sort(a + 1, a + n + 1);
for (register int i = 1; i <= n; ++i) if (a[i] >= 1 && a[i] <= n && !Vis[a[i]]) Vis[a[i]] = 1;
else T[++Top] = a[i];
Top = 0;
for (register int i = 1; i <= n; ++i)
if (!Vis[i]) {
++Top;
if (T[Top] <= i << 1) {
flag = 1;
break;
} else ++Answer;
}
if (flag) puts("-1");
else Quick_Write(Answer), puts("");
}
return 0;
}