E. Klever Permutation
E. Klever Permutation
You are given two integers and (), where is even.
A permutation of length is an array consisting of distinct integers from to in any order. For example, is a permutation, but is not a permutation (as appears twice in the array) and is also not a permutation (as , but is not present in the array).
Your task is to construct a -level permutation of length .
A permutation is called -level if, among all the sums of continuous segments of length (of which there are exactly ), any two sums differ by no more than .
More formally, to determine if the permutation is -level, first construct an array of length , where , i.e., the -th element is equal to the sum of .
A permutation is called -level if .
Find any -level permutation of length .
Input
The first line of the input contains a single integer () — 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 and (, is even), where is the length of the desired permutation.
It is guaranteed that the sum of for all test cases does not exceed .
Output
For each test case, output any -level permutation of length .
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:
;
.
The maximum among the sums is , and the minimum is .
解题思路
构造题直接投降,卡到比赛结束都没想出来,鉴定为弱智.jpg。
首先相邻的 和 必然不同,这是因为 ,由于 是排列因此必然有 ,所以 和 至少相差 。由于还要保证所有的 中最大值与最小值的差不超过 ,假设 ,那么 的形式必然是 或者 。
假设构造的 是这样的 ,那么根据 ,有 。同理可得 ,,,以此类推。发现如果是奇数下标,那么就有 ,否则是偶数下标就有 。
构造 的方法是把 分成 组,由于题目保证 是偶数,因此同一组中元素的下标 的奇偶性是相同的。所以可以开两个变量 ,,对于奇数的组从左到右遍历组中每个元素,赋值为 ,然后令 。同理对于偶数的组从左到右遍历组中每个元素,赋值为 ,然后令 。
AC 代码如下,时间复杂度为 :
#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
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/18012779
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2023-02-10 E. Sum Over Zero
2022-02-10 蹄球