Codeforces 873D. Merge Sort 分治 + 构造

来源:互联网 发布:mysql如何删除数据库 编辑:程序博客网 时间:2024/06/17 13:07

传送门:Codeforces 873D

题意:给出一种特殊的归并排序,分治的方法同普通的归并排序一样,只是如果当前待排序的区间已经是有序的,就不会再继续递归了,让你构造一个会调用k次mergesort函数的序列。

思路:因为我们上来就会调用一次mergesort函数,并且只要当前待排序区间不是有序的,那么在该层递归里就会调用两次mergesort,因此可以推出总调用次数一定是个奇数。然后我们递归的构造答案序列(令答案序列初始有序),若k > 2, 我们就将当前区间的a[mid]和a[mid - 1]交换一下,这样可以保证下一层递归传进去的区间一定是个有序区间,这不会样影响k==1时候的退出(按照题给定义,必须当前区间有序才能退出)。交换后k就少了2,一直这样递归构造,出口就是l + 1 == r或者k == 1.

代码:

#include<bits/stdc++.h>using namespace std;const int MAXN = 100010;int a[MAXN];int n, k;void dfs(int l, int r){    if(k == 1 || l + 1 == r) return ;    k -= 2;    int mid = (l + r) >> 1;    swap(a[mid], a[mid - 1]);    dfs(l, mid);    dfs(mid, r);}int main(){    cin >> n >> k;    if(k % 2 == 0) {        cout << -1;        return 0;    }    for(int i = 0; i < n; i++) a[i] = i + 1;    dfs(0, n);    if(k != 1) cout << -1;    else    for(int i = 0; i < n; i++)        printf("%d ", a[i]);}


原创粉丝点击