Educational Codeforces Round 30 D. Merge Sort 思维,二分

D. Merge Sort

题意: 给出 n 和 k ,然后要你确定一个长度为 n 的数组,要如下恰好调用 k 次 mergesort 函数

  1. 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;
  2. Let ;
  3. Call mergesort(a, l, mid);
  4. Call mergesort(a, mid, r);
  5. 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;
}
原文地址:https://www.cnblogs.com/sbfhy/p/7704830.html