归并排序的逆操作,每次二分时把第二段第一位与第一段最后一位开始往前第一个比它大的数交换位置
可以用归并排序验证答案对不对
#include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pii pair<int,int> #define C 0.5772156649 #define pi acos(-1.0) #define ll long long #define mod 1000000007 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const double g=10.0,eps=1e-7; const int N=100000+10,maxn=10000+100,inf=0x3f3f3f3f; int a[N],b[N],k,res; void rmergesort(int l,int r) { if(l==r||k<=0)return ; k-=2; int m=(l+r)>>1; if((r-l)%2==0)m--; // cout<<l<<" "<<m<<" "<<r<<endl; int ans=a[m+1],id=m+1; for(int i=m;i>=l;i--) { if(ans>a[i]) { ans=a[i]; id=i; break; } } swap(a[id],a[m+1]); rmergesort(l,m); rmergesort(m+1,r); } void mergesort(int l,int r) { res++; bool f=0; for(int i=l+1;i<=r;i++) { if(a[i]<a[i-1]) { f=1; break; } } if(!f)return ; int m=(l+r)>>1; if((r-l)%2==0)m--; mergesort(l,m); mergesort(m+1,r); int p1=l,p2=m+1,i=l; while(i<=r) { if(p1>m)b[i]=a[p2++]; else if(p2>r)b[i]=a[p1++]; else { if(a[p1]>a[p2])b[i]=a[p2++]; else b[i]=a[p1++]; } i++; } for(int i=l;i<=r;i++) a[i]=b[i]; } int main() { int n; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)a[i]=i; k--; rmergesort(1,n); if(k!=0)puts("-1"); else { for(int i=1; i<=n; i++) printf("%d ",a[i]); puts(""); } /* res=0; mergesort(1,n); for(int i=1;i<=n;i++) printf("%d ",a[i]); puts(""); cout<<k<<" "<<res<<endl;*/ return 0; } /******************** ********************/