【归并排序】【逆序数】HDU 5775 Bubble Sort

题目链接:

  http://acm.hdu.edu.cn/showproblem.php?pid=5775

题目大意

  冒泡排序的规则如下,一开始给定1~n的一个排列,求每个数字在排序过程中出现的最远端位置的差。

for(int i=1;i<=N;++i)
    for(int j=N,t;j>i;—j)
        if(P[j-1] > P[j])
            t=P[j],P[j]=P[j-1],P[j-1]=t;

  

题目思路:

  【归并排序】【逆序数】

  首先,一个数左移次数和右移次数时确定的(左边比它大的个数和右边比它小的个数)

  根据规则,每一次都是找第i小的数交换到位置i上,所以一个数只会往左一次,不存在先往左移动再往右移动再往左移动。

  所以一个数最远端位置差就为这两个数的最大值。

  那么可以先通过归并排序求出一个数右边比它小的数的个数ai,通过计算就知道左边比它大的个数,然后取max。

 1 //
 2 //by coolxxx
 3 //
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<string>
 7 #include<iomanip>
 8 #include<memory.h>
 9 #include<time.h>
10 #include<stdio.h>
11 #include<stdlib.h>
12 #include<string.h>
13 //#include<stdbool.h>
14 #include<math.h>
15 #define min(a,b) ((a)<(b)?(a):(b))
16 #define max(a,b) ((a)>(b)?(a):(b))
17 #define abs(a) ((a)>0?(a):(-(a)))
18 #define lowbit(a) (a&(-a))
19 #define sqr(a) ((a)*(a))
20 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
21 #define eps (1e-8)
22 #define J 10000000
23 #define MAX 0x7f7f7f7f
24 #define PI 3.1415926535897
25 #define N 100004
26 using namespace std;
27 typedef long long LL;
28 int cas,cass;
29 int n,m,lll,ans;
30 int p[N],a[N],b[N],le[N],ri[N],num[N];
31 void merge(int s[],int l,int mid,int r)
32 {
33     int i,j,k,n1=mid-l+1,n2=r-mid;
34     for(i=1;i<=n1;i++)le[i]=s[l+i-1];
35     for(i=1;i<=n2;i++)ri[i]=s[mid+i];
36     le[n1+1]=ri[n2+1]=MAX;
37     for(i=j=1,k=l;k<=r;k++)
38     {
39         if(le[i]<=ri[j])
40             s[k]=le[i++];
41         else
42             s[k]=ri[j++],b[s[k]]+=n1-i+1;
43     }
44 }
45 void mergesort(int s[],int l,int r)
46 {
47     int mid=(l+r)>>1;
48     if(l<r)
49     {
50         mergesort(s,l,mid);
51         mergesort(s,mid+1,r);
52         merge(s,l,mid,r);
53     }
54 }
55 int main()
56 {
57     #ifndef ONLINE_JUDGE
58     freopen("1.txt","r",stdin);
59 //    freopen("2.txt","w",stdout);
60     #endif
61     int i,j;
62 //    for(scanf("%d",&cas);cas;cas--)
63     for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
64 //    while(~scanf("%s",s))
65 //    while(~scanf("%d",&n))
66     {
67         memset(b,0,sizeof(num));
68         printf("Case #%d: ",cass);
69         scanf("%d",&n);
70         for(i=1;i<=n;i++)
71         {
72             scanf("%d",&num[i]);
73             p[num[i]]=i;
74         }
75         mergesort(num,1,n);
76         for(i=1;i<=n;i++)
77             a[i]=b[i]+i-p[i];
78         for(i=1;i<=n;i++)
79             printf("%d%c",max(a[i],b[i]),i==n?'
':' ');
80     }
81     return 0;
82 }
83 /*
84 //
85     
86 //
87 */
View Code
原文地址:https://www.cnblogs.com/Coolxxx/p/5769550.html