CF1617C Paprika and Permutation 题解 贪心

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 1in) 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 1t104) — 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 1n105).

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 1ai109).

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 2105.

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 1in )和 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 1t104 ) - 测试用例数。测试用例说明如下。

每个测试用例的第一行都包含一个整数 n n n ( 1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105 )。

每个测试用例的第二行包含 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 1ai109 ).

保证所有测试用例中 n n n 的总和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2105

输出

对于每个测试用例,输出使数组成为从 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 1n 的序列,要求最小的取模次数(如果无解,则输出 − 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,2n1⌋] 区间内。证明如下:

  • 对于“ 0 0 0”,就是 x x x 整除 y y y 的情况;
  • 对于“ ⌊ n − 1 2 ⌋ \lfloor\frac{n-1}{2}\rfloor 2n1”,显然为了余数尽可能大,则除数要尽可能大,当除数为 ⌈ 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;
}
  • 40
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值