【模板】归并排序及其应用

一、归并排序

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int a[10010];//实际排序数组 
 4 int b[10010];//辅助排序数组 
 5 int c[20030];
 6 void merge_sort(int l,int r){
 7     if(l==r){
 8         return;
 9     }
10     int mid = (l+r)>>1;
11     merge_sort(l,mid);
12     merge_sort(mid+1,r);
13     
14     int i = l,j = mid+1,k=l;
15     while(i<=mid&&j<=r){
16         if(a[i]<=a[j]){
17             b[k++] = a[i];
18             i++;
19         }else{
20             b[k++] = a[j];
21             j++;
22         }
23     }
24     while(i<=mid){
25         b[k++] = a[i];
26         i++;
27     }
28     while(j<=r){
29         b[k++] = a[j];
30         j++;
31     }
32     for(int p = l;p<=r;p++){
33         a[p] = b[p],b[p] = 0;
34     }
35     
36     
37 }
38 int n;
39 int main(){
40     cin>>n;
41     for(int i = 1;i<=n;i++){
42         cin>>a[i];
43     }
44     merge_sort(1,n);
45     for(int i = 1;i<=n;i++){
46         cout<<a[i]<<' ';
47     }
48     return 0;
49 }
View Code

二、merge函数

现有a数组,b数组,及用于存放结果的c数组,下标分别为1~n1,1~n2,1~n1+n2,且a与b保证有序

用法:merge(a+1,a+n1+1,b+1,b+n+1,c+1);

作用:将ab数组合并成一个有序数组,结果为c

三、瑞士轮

链接:https://www.luogu.com.cn/problem/P1309

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 struct node{
 4     int w;
 5     int s;
 6     int bian;
 7 }e[200010];
 8 bool cmp(const node &a,const node &b){
 9     if(a.s!=b.s){
10         return a.s>b.s;
11     }else{
12         return a.bian<b.bian;
13     }
14 }
15 node a[200010];
16 node b[100010];
17 node c[200010];
18 int n,r,q;
19 int main(){
20     cin>>n>>r>>q;
21     for(int i = 1;i<=2*n;i++){
22         cin>>e[i].s;
23         e[i].bian = i;
24     }
25     for(int i = 1;i<=2*n;i++){
26         cin>>e[i].w;
27     }
28     sort(e+1,e+2*n+1,cmp);
29     int biao1 = 0,biao2 = 0;
30     for(int i = 1;i<=r;i++){
31         biao1 = 0,biao2 = 0;
32         for(int j = 1;j<=2*n-1;j+=2){
33             if(e[j].w>e[j+1].w){
34                 e[j].s++;
35                 a[biao1++] = e[j]; 
36                 b[biao2++] = e[j+1];
37             }else{
38                 e[j+1].s++;
39                 a[biao1++] = e[j+1];
40                 b[biao2++] = e[j];
41             }
42         }
43         merge(a,a+biao1,b,b+biao2,e+1,cmp);
44     }
45     cout<<e[q].bian<<endl;
46     return 0;
47 }
View Code

思路:结构体存各选手信息

开两个数组记录每次比赛的胜者组,败者组,最后merge

四、逆序对

链接:https://www.luogu.com.cn/problem/P1908#submit

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 long long a[500100];//实际排序数组 
 4 long long b[500100];//辅助排序数组 
 5 long long ans;
 6 void merge_sort(long long l,long long r){
 7     if(l==r){
 8         return;
 9     }
10     long long mid = (l+r)>>1;
11     merge_sort(l,mid);
12     merge_sort(mid+1,r);
13     
14     int i = l,j = mid+1,k=l;
15     while(i<=mid&&j<=r){
16         if(a[i]<=a[j]){
17             b[k++] = a[i];
18             i++;
19         }else{
20             ans+=mid-i+1;
21             b[k++] = a[j];
22             j++;
23         }
24     }
25     while(i<=mid){
26         b[k++] = a[i];
27         i++;
28     }
29     while(j<=r){
30         b[k++] = a[j];
31         j++;
32     }
33     for(int p = l;p<=r;p++){
34         a[p] = b[p],b[p] = 0;
35     }
36     
37     
38 }
39 int n;
40 int main(){
41     cin>>n;
42     for(int i = 1;i<=n;i++){
43         scanf("%lld",&a[i]);
44     }
45     ans = 0;
46     merge_sort(1,n);
47     cout<<ans<<endl;
48     return 0;
49 }
View Code

猜你喜欢

转载自www.cnblogs.com/Xinaop/p/13374678.html