题意简述
给定n,kn,kn,k,求一个长度为nnn的数列,使得对它进行归并排序要调用kkk次MergeSortMergeSortMergeSort函数。
注:MergeSortMergeSortMergeSort:对l,midl,midl,mid和mid,rmid,rmid,r进行分治操作,如果有序,直接返回(不过也是要算一次调用)。否则就合并一下再返回。
思路(水题,一句解决)
初始化为1,2,3...n1,2,3...n1,2,3...n,写一个归并出来,如果要多一次操作,只要把左右两半的第一个位置换一下即珂,然后左右分别操作求解。
代码
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 155555
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
int n,k;
void Input()
{
cin>>n>>k;
}
int a[N];
void Sort(int l,int r) //精髓
{
if (!k or l>=r-1) return;
int mid=(l+r)>>1;
swap(a[mid-1],a[mid]);
--k;
Sort(l,mid);Sort(mid,r);
}
void Soviet()
{
if (k%2==0) return (void)puts("-1");
k/=2;
F(i,1,n) a[i]=i;
Sort(1,n+1);
if (k) return (void)puts("-1");
else
{
F(i,1,n) printf("%d ",a[i]);
putchar('\n');
}
}
#define Flan void
Flan IsMyWife()
{
Input();
Soviet();
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}
本文详细解析Codeforces 873D题目,探讨如何构造一个长度为n的数列,使其在进行归并排序时调用k次MergeSort函数。通过分析归并排序的分治策略,提出一种简单的解决方案:初始化数列为1到n,当需要增加操作次数时,交换左右子序列的第一个元素。接着递归地对左右子序列进行相同操作,最终得出满足条件的数列。
2163

被折叠的 条评论
为什么被折叠?



