Codeforces Round #761 (Div. 2) C. Paprika and Permutation

题目链接:Problem - C - Codeforces

Paprika loves permutations. She has an array a1,a2,…,an. She wants to make the array a permutation of integers 1 to n.

In order to achieve this goal, she can perform operations on the array. In each operation she can choose two integers i (1≤i≤n) and x (x>0), then perform ai:=aimodx (that is, replace ai by the remainder of ai divided by x). In different operations, the chosen i and x can be different.

Determine the minimum number of operations needed to make the array a permutation of integers 1 to n. If it is impossible, output −1.

A permutation is an array consisting of n distinct integers from 1 to n in arbitrary order. For example, [2,3,1,5,4] is a permutation, but [1,2,2] is not a permutation (2 appears twice in the array) and [1,3,4] is also not a permutation (n=3 but there is 4 in the array).

Input

Each test contains multiple test cases. The first line contains a single integer t (1≤t≤104) — the number of test cases. Description of the test cases follows.

The first line of each test case contains an integer nn (1≤n≤105).

The second line of each test case contains nn integers a1,a2,…,an. (1≤ai≤109).

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅105.

Output

For each test case, output the minimum number of operations needed to make the array a permutation of integers 1 to n, or −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, x=5. Perform a2:=a2mod5=2.

For the second test, it is impossible to obtain a permutation of integers from 1 to n.

题意:给定一个序列,可以任选一个值mod一个随机值,然后使这个序列变成(1 - n)的排列

思路:一个数如果是奇数,那么他就可以变成(1 - n / 2),否则就可以变成(1 - n / 2 - 1)

我们可以先求出缺少的递增值,然后把序列排序一下,看看能不能从不行的值转变过去

#include<bits/stdc++.h>
using namespace std;

long long arr[100005];
vector<long long> ve;
bool vis[100005];

int main(){
	ios::sync_with_stdio(false); 
	int t;
	int n;
	cin >> t;
	while(t--){
		cin >> n;
		for(int i = 0; i <= n; i++){
			vis[i] = 0;
		}
		ve.clear();
		for(int i = 0; i < n; i++){
			cin >> arr[i];
			if(arr[i] <= n){
				vis[arr[i]] = 1;
			}
		}
		sort(arr, arr + n);
		for(int i = 1; i <= n; i++){
			if(vis[i] == 0){
				ve.push_back(i);
			}
		}
		int l = 0;
		bool flag = 0;
		int sum = 0;
		for(int i = 0; i < n; i++){
			if(arr[i] > n){
				int ans = arr[i] / 2;
				if(arr[i] % 2 == 0){
					ans--;
				}
				if(ans >= ve[l]){
					l++;
				}else{
					flag = 1;
					break;
				}
				continue;
			}
			if(i >= 1 && arr[i] == arr[i - 1]){
				int ans = arr[i] / 2;
				if(arr[i] % 2 == 0){
					ans--;
				}
				if(ans >= ve[l]){
					l++;
				}else{
					flag = 1;
					break;
				}
			}
		}
		if(flag){
			cout << -1 << endl;
		}else{
			cout << ve.size() << endl;
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值