归并排序模板:
void mergesort(int left,int right){
if(left>=right) return ;
int mid=(left+right)/2;
mergesort(left,mid);
mergesort(mid+1,right);
int i=left,j=mid+1,k=0;
while(i<=mid&&j<=right){
if(arr[i]<=arr[j]) temp[k++]=arr[i++];
else temp[k++]=arr[j++];
}
while(i<=mid) temp[k++]=arr[i++];
while(j<=right) temp[k++]=arr[j++];
for(int i=left,j=0;j<k;i++,j++) arr[i]=temp[j];
}
题目:
Acwing 505. 火柴排队
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+5,mod=99999997;
int n,a[N],b[N],p[N],q[N],ans;
void work(int arr[]){
for(int i=1;i<=n;i++) p[i]=i;
sort(p+1,p+1+n,[&](int x,int y){return arr[x]<arr[y];});
for(int i=1;i<=n;i++) arr[p[i]]=i;
}
void mergesort(int left,int right){
if(left>=right) return ;
int mid=(left+right)/2;
mergesort(left,mid);
mergesort(mid+1,right);
int i=left,j=mid+1,k=0;
while(i<=mid&&j<=right){
if(b[i]<=b[j]) q[k++]=b[i++];
else q[k++]=b[j++],ans+=mid-i+1,ans%=mod;//求逆序对
}
while(i<=mid) q[k++]=b[i++];
while(j<=right) q[k++]=b[j++];
for(int i=left,j=0;j<k;i++,j++) b[i]=q[j];
}
int main(){
//输入
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
//离散化
work(a),work(b);
//映射
for(int i=1;i<=n;i++) q[a[i]]=i;
for(int i=1;i<=n;i++) b[i]=q[b[i]];
//归并排序
mergesort(1,n);
//输出
cout<<ans<<endl;
return 0;
}
AcWing 1215. 小朋友排队(第五届省赛)
暴力法 未AC(60 points):
#include<iostream>
using namespace std;
const int N=1e5+5;
int n,a[N],flag[N];
long long ans;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
//每个数所对应的换位次数==前面比它大的个数+后面比它小的个数
for(int i=0;i<n;i++){
long long cnt=0;
for(int j=0;j<i;j++){
if(a[j]>a[i]){
cnt++;
}
}
for(int j=i+1;j<n;j++){
if(a[j]<a[i]){
cnt++;
}
}
//计算
long long temp=0;
temp=(cnt+1)*cnt/2;
flag[i]=temp;
}
for(int i=0;i<N;i++) ans+=flag[i];
cout<<ans<<endl;
}
AcWing 107. 超快速排序
#include<iostream>
using namespace std;
const int N=5e5+5;
int n,a[N],p[N];
long long ans;
void mergesort(int left,int right){
if(left>=right) return ;
int mid=(left+right)/2;
mergesort(left,mid);
mergesort(mid+1,right);
int i=left,j=mid+1,k=0;
while(i<=mid&&j<=right){
if(a[i]<=a[j]) p[k++]=a[i++];
else p[k++]=a[j++],ans+=mid-i+1;
}
while(i<=mid) p[k++]=a[i++];
while(j<=right) p[k++]=a[j++];
for(int i=left,j=0;j<k;i++,j++) a[i]=p[j];
return ;
}
int main(){
while(cin>>n){
if(n==0) return 0;
ans=0;
for(int i=1;i<=n;i++) cin>>a[i];
mergesort(1,n);
cout<<ans<<endl;
}
}