D. Merge Sort
题意: 给出 n 和 k ,然后要你确定一个长度为 n 的数组,要如下恰好调用 k 次 mergesort 函数。
- If the segment [l, r) is already sorted in non-descending order (that is, for any i such that l ≤ i < r - 1 a[i] ≤ a[i + 1]), then end the function call;
- Let ;
- Call mergesort(a, l, mid);
- Call mergesort(a, mid, r);
- Merge segments [l, mid) and [mid, r), making the segment [l, r) sorted in non-descending order. The merge algorithm doesn't call any other functions.
tags:类似于分治思想,多画两下会发 n 个数最多调用 2*n-1 次函数。 然后二分搜下去就是了。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 200005; int n, k, ans[N], cnt; bool flag; void dfs(int l, int r, int L, int R, int kk) { if(kk==1) { rep(i,L,R) printf("%d ", i); return ; } int mid=l+r>>1, num=mid-l; --kk; if(2*num-1 < kk-1) dfs(l, mid, R-num+1, R, 2*num-1); else dfs(l, mid, R-num+1, R, kk-1); kk -= min(2*num-1, kk-1); num=r-mid; dfs(mid, r, L, L+num-1, kk); } int main() { scanf("%d%d", &n, &k); if(k%2==0 || k>=2*n) return 0*printf("-1 "); dfs(0, n, 1, n, k); rep(i,1,cnt) printf("%d ", ans[i]); return 0; }