Codeforces Round #813 (Div. 2) 题解 (A~C)

发布于:2023-01-04 ⋅ 阅读:(261) ⋅ 点赞:(0)

A. Wonderful Permutation

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Problem Statement

You are given a permutation p 1 , p 2 , … , p n p_1,p_2,…,p_n p1,p2,,pn of length n and a positive integer k ≤ n k≤n kn.

In one operation you can choose two indices i i i and j j j ( 1 ≤ i < j ≤ n ) (1≤i<j≤n) (1i<jn) and swap p i p_i pi with p j p_j pj.

Find the minimum number of operations needed to make the sum p 1 + p 2 + … + p k p_1+p_2+…+p_k p1+p2++pk as small as possible.

A permutation is an array consisting of n n n distinct integers from 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).

题面翻译

给出一个长度为 n n n的排列 p 1 , p 2 , . . . , p n p_1,p_2,...,p_n p1,p2,...,pn和一个正整数 k k k

在每一次操作中,你可以交换任意的 a i , a j ( 1 ≤ i , j ≤ n ) a_i,a_j(1 \le i,j \le n) ai,aj(1i,jn)

求当 p 1 + p 2 + . . . + p k p_1+p_2+...+p_k p1+p2+...+pk最小时,最少的操作次数。

定义:排列是指有 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也在数组中)。

Input

Each test contains multiple test cases. The first line contains the number of test cases t ( 1 ≤ t ≤ 100 ) t (1≤t≤100) t(1t100). Description of the test cases follows.

The first line of each test case contains two integers n n n and k ( 1 ≤ k ≤ n ≤ 100 ) k (1≤k≤n≤100) k(1kn100).

The second line of each test case contains n n n integers p 1 , p 2 , … , p n ( 1 ≤ p i ≤ n ) p_1,p_2,…,p_n (1≤p_i≤n) p1,p2,,pn(1pin). It is guaranteed that the given numbers form a permutation of length n n n.

Output

For each test case print one integer — the minimum number of operations needed to make the sum p 1 + p 2 + … + p k p_1+p_2+…+p_k p1+p2++pk as small as possible.

Example

input

4
3 1
2 3 1
3 3
1 2 3
4 2
3 4 1 2
1 1
1

output

1
0
2
0

Note
In the first test case, the value of p 1 + p 2 + … + p k p_1+p_2+…+p_k p1+p2++pk is initially equal to 2 2 2, but the smallest possible value is 1 1 1. You can achieve it by swapping p 1 p_1 p1 with p 3 p_3 p3, resulting in the permutation [ 1 , 3 , 2 ] [1,3,2] [1,3,2].

In the second test case, the sum is already as small as possible, so the answer is 0 0 0.

题解部分

既然这个数组是一个排列,那最小的 k k k个数一定是 1 , 2 , . . . , k 1,2,...,k 1,2,...,k,所以我们只需要看 p 1 , p 2 , . . . , p k p_1,p_2,...,p_k p1,p2,...,pk中有多少个大于 k k k的数,就是要交换掉的数。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
 
const int MAXN = 100 + 5; 
int T, n, k, a[MAXN], minn, minp, cnt;
 
int main () {
	scanf ("%d", &T);
	while (T --) {
		scanf ("%d %d", &n, &k);
		for (int i = 1; i <= n; i ++) {
			scanf ("%d", &a[i]);
		}
		cnt = 0;
		for (int i = 1; i <= k; i ++) {
			if (a[i] <= k) {
				cnt ++;
			}
		}
		printf ("%d\n", k - cnt);
	}
	return 0;
}

B. Woeful Permutation

time limit per test: 1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Problem Statement

You are given a positive integer n n n.

Find any permutation p p p of length n n n such that the sum l c m ( 1 , p 1 ) + l c m ( 2 , p 2 ) + … + l c m ( n , p n ) lcm(1,p_1)+lcm(2,p_2)+…+lcm(n,p_n) lcm(1,p1)+lcm(2,p2)++lcm(n,pn) is as large as possible.

Here l c m ( x , y ) lcm(x,y) lcm(x,y) denotes the least common multiple (LCM) of integers x x x and y y y.

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

题面翻译

给出一个数 n n n,求出长度为 n n n的排列 p p p使得 l c m ( 1 , p 1 ) + l c m ( 2 , p 2 ) + … + l c m ( n , p n ) lcm(1,p_1)+lcm(2,p_2)+…+lcm(n,p_n) lcm(1,p1)+lcm(2,p2)++lcm(n,pn)最大,若答案不唯一,随机输出一组。

Input

Each test contains multiple test cases. The first line contains the number of test cases t ( 1 ≤ t ≤ 1000 ) t (1≤t≤1000) t(1t1000). Description of the test cases follows.

The only line for each test case contains a single integer n ( 1 ≤ n ≤ 1 0 5 ) n (1≤n≤10^5) n(1n105).

It is guaranteed that the sum of n n n over all test cases does not exceed 1 0 5 10^5 105.

Output

For each test case print n integers p 1 , p 2 , … , p n p_1, p_2, …, p_n p1,p2,,pn — the permutation with the maximum possible value of l c m ( 1 , p 1 ) + l c m ( 2 , p 2 ) + … + l c m ( n , p n ) lcm(1,p_1)+lcm(2,p_2)+…+lcm(n,p_n) lcm(1,p1)+lcm(2,p2)++lcm(n,pn).

If there are multiple answers, print any of them.

Example

input

2
1
2

output

1 
2 1 

Note
For n = 1 n=1 n=1, there is only one permutation, so the answer is [ 1 ] [1] [1].

For n = 2 n=2 n=2, there are two permutations:

[ 1 , 2 ] [1,2] [1,2] — the sum is l c m ( 1 , 1 ) + l c m ( 2 , 2 ) = 1 + 2 = 3 lcm(1,1)+lcm(2,2)=1+2=3 lcm(1,1)+lcm(2,2)=1+2=3.
[ 2 , 1 ] [2,1] [2,1] — the sum is l c m ( 1 , 2 ) + l c m ( 2 , 1 ) = 2 + 2 = 4 lcm(1,2)+lcm(2,1)=2+2=4 lcm(1,2)+lcm(2,1)=2+2=4.

题解部分

众所周知,相邻的两个数互质,也就是说 gcd ⁡ ( k , k + 1 ) = 1 \gcd(k,k+1)=1 gcd(k,k+1)=1

而且还有这样一个性质: gcd ⁡ ( a , b ) × l c m ( a , b ) = a b \gcd(a,b) \times lcm(a,b)=ab gcd(a,b)×lcm(a,b)=ab

∴ l c m ( k , k + 1 ) = k 2 + k \therefore lcm(k,k+1)=k^2+k lcm(k,k+1)=k2+k

那么,我们尽量让 k k k越大越好,所以相邻两个数就可以这样求 l c m lcm lcm,使得代价最小且乘积最大。

先来讨论一下 k k k为奇数的情况:

我们只用比较下面两种情况中的较大值:

i i i 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 . . . ... ... k − 2 k-2 k2 k − 1 k-1 k1 k k k
情况 1 1 1 2 2 2 1 1 1 4 4 4 3 3 3 6 6 6 5 5 5 . . . ... ... k − 1 k-1 k1 k − 2 k-2 k2 k k k
情况 2 2 2 1 1 1 3 3 3 2 2 2 5 5 5 4 4 4 7 7 7 . . . ... ... k − 3 k-3 k3 k k k k − 1 k-1 k1

情况 1 1 1是从前往后两两分成一组,最后单出来一个 k k k,情况 2 2 2是从后往前两两分成一组,最后单出来一个 1 1 1

那么情况 1 1 1的结果为 1 × 2 + 3 × 4 + 5 × 6 + . . . + ( k − 2 ) ( k − 1 ) + k 1 \times 2+3 \times 4+5 \times 6+...+(k-2)(k-1)+k 1×2+3×4+5×6+...+(k2)(k1)+k

情况 2 2 2的结果为 1 + 2 × 3 + 4 × 5 + 6 × 7 + . . . + ( k − 1 ) ⋅ k 1+2 \times 3+4 \times 5+6 \times 7+...+(k-1) \cdot k 1+2×3+4×5+6×7+...+(k1)k

要比较两式的结果,用的方法是两式相减。

① ① − ② -② 式得: − 2 ( 2 + 4 + 6 + . . . + k − 1 ) + k − 1 -2(2+4+6+...+k-1)+k-1 2(2+4+6+...+k1)+k1

k − 1 > 2 ( 2 + 4 + 6 + . . . + k − 1 ) k-1>2(2+4+6+...+k-1) k1>2(2+4+6+...+k1),则原式为正,否则为非正。

我们就解这个不等式,

k − 1 > 4 ( 1 + 2 + 3 + . . . + k − 1 2 ) k-1>4(1+2+3+...+ \frac{k-1}{2}) k1>4(1+2+3+...+2k1)

k − 1 > 4 × ( 1 + k − 1 2 ) ⋅ k − 1 2 2 k-1>4 \times \frac{(1+\frac{k-1}{2}) \cdot \frac{k-1}{2}}{2} k1>4×2(1+2k1)2k1

k − 1 > ( k − 1 ) ( 1 + k − 1 2 ) k-1>(k-1)(1+\frac{k-1}{2}) k1>(k1)(1+2k1)

因为题目条件中 k ≤ 1 k \le 1 k1,所以 k − 1 ≤ 0 k-1 \le 0 k10,当 k − 1 = 0 k-1=0 k1=0时无意义,当 k > 1 k>1 k>1时:

1 + k − 1 2 < 1 1+\frac{k-1}{2}<1 1+2k1<1

k − 1 2 < 0 \frac{k-1}{2}<0 2k1<0

k < 1 k<1 k<1

这明显与题目不符,所以若满足题目条件, k ≤ 1 k \le 1 k1,这时,原式为负,所以情况 2 2 2更优。

再来讨论一下 k k k为偶数的情况,这只有一种情况,即:

i i i 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 . . . ... ... k − 1 k-1 k1 k k k
情况 2 2 2 1 1 1 4 4 4 3 3 3 6 6 6 5 5 5 . . . ... ... k k k k − 1 k-1 k1
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int T, n;

int main () {
	scanf ("%d", &T);
	while (T --) {
		scanf ("%d", &n);
		if (n % 2 == 1) {
			printf ("1 ");
			for (int i = 2; i <= n; i ++) {
				if (i % 2) {
					printf ("%d ", i - 1);
				} else {
					printf ("%d ", i + 1);
				}
			}
		} else {
			for (int i = 1; i <= n; i ++) {
				if (i % 2) {
					printf ("%d ", i + 1);
				} else {
					printf ("%d ", i - 1);
				}
			}
		}
		printf ("\n");
	}
	return 0;
}

C. Sort Zero

time limit per test:1 second
memory limit per test: 256 megabytes
input: standard input
output: standard output

Problem Statement

You are given an array of n n n positive integers a 1 , a 2 , … , a n a_1,a_2,…,a_n a1,a2,,an.

In one operation you do the following:

Choose any integer x x x.
For all i i i such that a i = x a_i=x ai=x, do a i : = 0 a_i:=0 ai:=0 (assign 0 0 0 to a i a_i ai).
Find the minimum number of operations required to sort the array in non-decreasing order.

Input

Each test contains multiple test cases. The first line contains the number of test cases t ( 1 ≤ t ≤ 1 0 4 ) t (1≤t≤10^4) t(1t104). Description of the test cases follows.

The first line of each test case contains a single integer n ( 1 ≤ n ≤ 1 0 5 ) n (1≤n≤10^5) n(1n105).

The second line of each test case contains n n n positive integers a 1 , a 2 , … , a n ( 1 ≤ a i ≤ n ) a_1,a_2,…,a_n (1≤a_i≤n) a1,a2,,an(1ain).

It is guaranteed that the sum of n n n over all test cases does not exceed 1 0 5 10_5 105.

Output

For each test case print one integer — the minimum number of operations required to sort the array in non-decreasing order.

题面翻译

给出一个长度为 n n n的数组,你每次要进行以下操作:

任意取一个数 x x x,并将数组中所有 a i = x a_i=x ai=x a i a_i ai修改为 0 0 0

求最小需要修改多少次,才能是整个数组成为一个非下降数列。

Example

input

5
3
3 3 2
4
1 3 1 3
5
4 1 5 3 2
4
2 4 1 2
1
1

output

1
2
4
3
0

Note
In the first test case, you can choose x = 3 x=3 x=3 for the operation, the resulting array is [ 0 , 0 , 2 ] [0,0,2] [0,0,2].

In the second test case, you can choose x = 1 x=1 x=1 for the first operation and x = 3 x=3 x=3 for the second operation, the resulting array is [ 0 , 0 , 0 , 0 ] [0,0,0,0] [0,0,0,0].

题解部分

模拟法。用一个while循环模拟筛数的过程。

#include <cstdio>
#include <set>
#include <cstring>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;

const int MAXN = 1e5 + 5;
int T, n, a[MAXN];
set <int> s;

int main () {
	scanf ("%d", &T);
	while (T --) {
		scanf ("%d", &n);
		for (int i = 1; i <= n; i ++) {
			scanf ("%d", &a[i]);
		}
		int cnt = 0;
		bool flag = 1;
		while (flag) {
			flag = 0;
			for (int i = n; i >= 1; i --) {
				if (a[i - 1] > a[i]) {
					s.clear();
					for (int j = i - 1; j >= 1; j --) {
						if (a[j] == 0) {
							break;
						}
						s.insert(a[j]);
					}
					cnt += s.size();//优化,第i个点不满足,a[i]=0,因为1<=a[i],所以i点之前的数>=0,所以前面的非0数同样不满足
					for (int j = 1; j <= n; j ++) {
						if (s.count(a[j]) != 0) {
							a[j] = 0;
						}
					}
					flag = 1;
					break;
				}
			}
		}
		printf ("%d\n", cnt);
	}
	return 0;
}
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到