E. Klever Permutation
You are given two integers $n$ and $k$ ($k \le n$), where $k$ is even.
A permutation of length $n$ is an array consisting of $n$ distinct integers from $1$ to $n$ in any order. For example, $[2,3,1,5,4]$ is a permutation, but $[1,2,2]$ is not a permutation (as $2$ appears twice in the array) and $[0,1,2]$ is also not a permutation (as $n=3$, but $3$ is not present in the array).
Your task is to construct a $k$-level permutation of length $n$.
A permutation is called $k$-level if, among all the sums of continuous segments of length $k$ (of which there are exactly $n - k + 1$), any two sums differ by no more than $1$.
More formally, to determine if the permutation $p$ is $k$-level, first construct an array $s$ of length $n - k + 1$, where $s_i=\sum_{j=i}^{i+k-1} p_j$, i.e., the $i$-th element is equal to the sum of $p_i, p_{i+1}, \dots, p_{i+k-1}$.
A permutation is called $k$-level if $\max(s) - \min(s) \le 1$.
Find any $k$-level permutation of length $n$.
Input
The first line of the input contains a single integer $t$ ($1 \le t \le 10^4$) — the number of test cases. This is followed by the description of the test cases.
The first and only line of each test case contains two integers $n$ and $k$ ($2 \le k \le n \le 2 \cdot 10^5$, $k$ is even), where $n$ is the length of the desired permutation.
It is guaranteed that the sum of $n$ for all test cases does not exceed $2 \cdot 10^5$.
Output
For each test case, output any $k$-level permutation of length $n$.
It is guaranteed that such a permutation always exists given the constraints.
Example
input
5
2 2
3 2
10 4
13 4
7 4
output
2 1
1 3 2
1 8 4 10 2 7 5 9 3 6
4 10 1 13 5 9 2 12 6 8 3 11 7
1 6 3 7 2 5 4
Note
In the second test case of the example:
$p_1 + p_2 = 3 + 1 = 4$;
$p_2 + p_3 = 1 + 2 = 3$.
The maximum among the sums is $4$, and the minimum is $3$.
解题思路
构造题直接投降,卡到比赛结束都没想出来,鉴定为弱智.jpg。
首先相邻的 $s_i$ 和 $s_{i+1}$ 必然不同,这是因为 $s_i - s_{i+1} = a_{i} - a_{i+k}$,由于 $a$ 是排列因此必然有 $a_{i} \ne a_{i+k}$,所以 $s_i$ 和 $s_{i+1}$ 至少相差 $1$。由于还要保证所有的 $s_i$ 中最大值与最小值的差不超过 $1$,假设 $s_1 = x$,那么 $s$ 的形式必然是 $[x,x+1,x,x+1,x,\ldots]$ 或者 $[x,x-1,x,x-1,x,\ldots]$。
假设构造的 $s$ 是这样的 $[x,x+1,x,x+1,x,\ldots]$,那么根据 $s_1 - s_2 = -1$,有 $a_1 = a_{1+k} + 1$。同理可得 $a_2 = a_{2+k} - 1$,$a_3 = a_{3+k} + 1$,$a_4 = a_{4+k} - 1$,以此类推。发现如果是奇数下标,那么就有 $a_i = a_{i+k}+1$,否则是偶数下标就有 $a_i = a_{i+k}+1$。
构造 $a$ 的方法是把 $a$ 分成 $k$ 组,由于题目保证 $k$ 是偶数,因此同一组中元素的下标 $i, \, i+k, \, i+2k, \, \ldots$ 的奇偶性是相同的。所以可以开两个变量 $l=1$,$r=n$,对于奇数的组从左到右遍历组中每个元素,赋值为 $l$,然后令 $l \gets l+1$。同理对于偶数的组从左到右遍历组中每个元素,赋值为 $r$,然后令 $r \gets r-1$。
AC 代码如下,时间复杂度为 $O(n)$:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int ans[N];
void solve() {
int n, m;
scanf("%d %d", &n, &m);
for (int i = 1, l = 1, r = n; i <= m; i++) {
for (int j = i; j <= n; j += m) {
if (i & 1) ans[j] = l++;
else ans[j] = r--;
}
}
for (int i = 1; i <= n; i++) {
printf("%d ", ans[i]);
}
printf("\n");
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
参考资料
Codeforces Round 923 (Div. 3) Editorial:https://codeforces.com/blog/entry/125597
标签:10,le,level,Klever,Permutation,length,permutation,test From: https://www.cnblogs.com/onlyblues/p/18012779