很简单的一个排序,先通过递归划分区间到最小(因为一个元素具有单调性),然后再合并两个单调区间为一个单调区间,具体看代码
模板:
void Merge(int l,int m,int r) { int i=l; int j=m+1; int k=l; while(i<=m&&j<=r) { if(a[i]>a[j]) { temp[k++]=a[j++]; } else temp[k++]=a[i++]; } while(i<=m)temp[k++]=a[i++]; while(j<=r)temp[k++]=a[j++]; for(int i=l;i<=r;i++) a[i]=temp[i]; } void Merge_sort(int l,int r) { if(l<r) { int m=(l+r)>>1; Merge_sort(l,m); Merge_sort(m+1,r); Merge(l,m,r); } }
例题1:POJ - 1804
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<queue> #include<map> #include<set> using namespace std; #define ll long long #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e3+5; int a[N]; int temp[N]; int cnt; void Merge(int l,int m,int r) { int i=l; int j=m+1; int k=l; while(i<=m&&j<=r) { if(a[i]>a[j]) { temp[k++]=a[j++]; cnt+=m-i+1; } else temp[k++]=a[i++]; } while(i<=m)temp[k++]=a[i++]; while(j<=r)temp[k++]=a[j++]; for(int i=l;i<=r;i++) a[i]=temp[i]; } void Merge_sort(int l,int r) { if(l<r) { int m=(l+r)>>1; Merge_sort(l,m); Merge_sort(m+1,r); Merge(l,m,r); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int T,n; cin>>T; int cs=0; while(T--) { cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; cnt=0; Merge_sort(1,n); cout<<"Scenario #"<<++cs<<":"<<endl<<cnt<<endl<<endl; } return 0; }
例题2:Codeforces 873D - Merge Sort
归并排序逆操作
#include<bits/stdc++.h> using namespace std; #define ll long long #define ls rt<<1,l,m #define rs rt<<1|1,m+1,r #define pb push_back #define mem(a,b) memset(a,b,sizeof(a)) const int N=1e5+5; const int INF=0x3f3f3f3f; int k,n; int a[N]; void Merge_sort(int l,int r) { if(!k)return ; if(l+1<r) { int m=(l+r)>>1; swap(a[m],a[m-1]); k--; k--; if(k) { Merge_sort(l,m); Merge_sort(m,r); } } else return ; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin>>n>>k; if(k&1) { for(int i=0;i<n;i++)a[i]=i+1; k--; if(k)Merge_sort(0,n); if(k)return 0*puts("-1"); for(int i=0;i<n;i++)cout<<a[i]<<' '; cout<<endl; } else cout<<-1<<endl; return 0; }