zoukankan      html  css  js  c++  java
  • CodeForces 873D Merge Sort 构造 分治

    题意

    给出一个归并排序的算法(mergesort),如果对于当前区间([l, r))是有序的,则函数直接返回。
    否则会分别调用(mergesort(l, mid))(mergesort(mid, r)),其中(mid = left lfloor frac{l+r}{2} ight floor)
    最后合并左右两个子区间

    下面请你构造一个(1 sim n)的排列,并且恰好调用(k)(mergesort)函数完成排序

    分析

    首先,对函数的调用次数一定是奇数次
    因为除去最开始对函数的调用,之后每次调用函数都是对左右区间成对调用的
    设一开始排列(p)是从(1)(n)的顺序排列
    模拟(mergesort)函数的调用进行构造,假设当前区间为([l,r),(r-l>1)),并且当前调用次数未满(k)
    那么交换(p[mid-1])(p[mid]),则区间([l,r))变为无序,函数调用次数增加(2)
    左右两个子区间仍然是有序的,不断递归进行处理直到调用次数等于(k)或对所有区间处理完毕

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define REP(i, a, b) for(int i = a; i < b; i++)
    
    const int maxn = 100000 + 10;
    
    int n, k;
    int a[maxn];
    
    void solve(int l, int r) {
    	if(!k || r - l == 1) return;
    	k--;
    	int mid = (l + r) / 2;
    	swap(a[mid], a[mid - 1]);
    	solve(l, mid);
    	solve(mid, r);
    }
    
    int main() {
    	scanf("%d%d", &n, &k);
    	k--;
    	if(k & 1) { printf("-1
    "); return 0; }
    	k >>= 1;
    	REP(i, 0, n) a[i] = i + 1;
    	solve(0, n);
    	if(k) printf("-1
    ");
    	else REP(i, 0, n) printf("%d ", a[i]);
    	printf("
    ");
    
    	return 0;
    }
    
  • 相关阅读:
    矩阵价值和
    排列组合问题
    X国的军队
    石子合并加强版
    P1042 乒乓球
    Dinner 点餐
    一文看尽图像分类问题
    [Udemy] Recommender Systems and Deep Learning in Python
    推荐系统学习
    [NLP] 酒店名归类
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/7668954.html
Copyright © 2011-2022 走看看