goj 小明滚出去?(求逆序数)

Problem Description:

老师:“小明,写一个排序算法”;
小明:
void mysort(int a[],int n) //n为数组a的元素个数
{
    int i,j;
    for(j=0;j< n-1;j++)
        for(i=0;i< n-1;i++)
        {
            if(a[i] >a[i+1])//数组元素大小按升序排列
            {
            	swap(a[i],a[i+1]);//交换
            }
        }
}
老师:“好,那么,问题来了,给定一个数组,按你这个算法排序,需要的交换次数是多少?回答对了今天就可以不用滚出去。”
小明按他的这个算法试了一下,发现超时了,不想天天被老师叫滚出去,小明只好求助于你,你能帮助小明今天不用滚出去么?

Input:

输入包含多组数据(EOF),每组数据第一行是一个整数n(1<=n<=10^5),第二行有n个整数(<=10^5);

Output:

对于每组数据,输出小明排序算法的交换次数。

Sample Input:

3
1 3 2
5
5 4 3 2 1
4
1 2 3 4

Sample Output:

1
10
0
解题思路:求冒泡排序的交换次数其实就是求这个序列的逆序数,归并排序水过!
AC代码一之归并排序:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+5;
 4 typedef long long LL;
 5 int n,a[maxn],tmp[maxn];LL ans;
 6 void _merge(int l,int m,int r){
 7     int i=l,j=m+1,k=l;
 8     while(i<=m&&j<=r){
 9         if(a[i]>a[j]){tmp[k++]=a[j++];ans+=(LL)m-i+1;}
10         else tmp[k++]=a[i++];
11     }
12     while(i<=m)tmp[k++]=a[i++];
13     while(j<=r)tmp[k++]=a[j++];
14     for(int i=l;i<=r;++i)a[i]=tmp[i];
15 }
16 void _merge_sort(int l,int r){
17     if(l<r){
18         int m=(l+r)>>1;
19         _merge_sort(l,m);
20         _merge_sort(m+1,r);
21         _merge(l,m,r);
22     }
23 }
24 int main(){
25     while(~scanf("%d",&n)){
26         for(int i=0;i<n;++i)scanf("%d",&a[i]);
27         ans=0;_merge_sort(0,n-1);
28         printf("%lld
",ans);
29     }
30     return 0;
31 }

 AC代码二之树状数组:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=100005;
 4 typedef long long LL;
 5 int n,val,aa[maxn],tar[maxn];
 6 struct node{int val,id;}nod[maxn];
 7 bool cmp(node a,node b){return a.val<b.val;}
 8 int lowbit(int x){return x & -x;}
 9 void update(int x,int val){
10     while(x<=n){aa[x]+=val;x+=lowbit(x);}
11 }
12 int getsum(int x){
13     int ret=0;
14     while(x>0){ret+=aa[x];x-=lowbit(x);}
15     return ret;
16 }
17 int main(){
18     while(cin>>n){
19         LL ans=0;
20         memset(aa,0,sizeof(aa));
21         for(int i=1;i<=n;++i){cin>>nod[i].val;nod[i].id=i;}
22         sort(nod+1,nod+n+1,cmp);
23         for(int i=1;i<=n;++i)tar[nod[i].id]=i;
24         for(int i=1;i<=n;++i){update(tar[i],1);ans+=i-getsum(tar[i]);}
25         cout<<ans<<endl;
26     }
27     return 0;
28 }
原文地址:https://www.cnblogs.com/acgoto/p/9219034.html