列表

详情


CMB21. 排队唱歌

描述

我们部门要排队唱歌,大家乱哄哄的挤在一起,现在需要按从低到高的顺序拍成一列,但每次只能交换相邻的两位,请问最少要交换多少次

输入描述

第一行是N(N<50000),表示有N个人
然后每一行是人的身高Hi(Hi<2000000,不要怀疑,我们以微米计数),持续N行,表示现在排列的队伍

输出描述

输出一个数,代表交换次数。

示例1

输入:

6
3
1
2
5
6
4

输出:

4

原站题解

C++ 解法, 执行用时: 6ms, 内存消耗: 1028KB, 提交时间: 2020-09-13

#include<bits/stdc++.h>
#define MAXN 50010
#define _2M 2000000
using namespace std;
typedef long long LL;
int n,maxh=0;
int bit[_2M+10],a[MAXN];
      
int sum(int x){
    int res=0;
    for(int i=x;i>0;i-=i&-i)res+=bit[i];
    return res;
}
      
void update(int x,int val){
    for(int i=x;i<=maxh;i+=i&-i)bit[i]+=val;
}
      
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",a+i),maxh=max(maxh,a[i]);
    LL ans=0;
    for(int i=n;i>=1;--i){
        ans+=sum(a[i]-1);
        update(a[i],1);
    }
    cout<<ans<<endl;
    return 0;
}

C++ 解法, 执行用时: 7ms, 内存消耗: 976KB, 提交时间: 2020-07-28

#include<bits/stdc++.h>
#define MAXN 50010
#define _2M 2000000
using namespace std;
typedef long long LL;
int n,maxh=0;
int bit[_2M+10],a[MAXN];
     
int sum(int x){
    int res=0;
    for(int i=x;i>0;i-=i&-i)res+=bit[i];
    return res;
}
     
void update(int x,int val){
    for(int i=x;i<=maxh;i+=i&-i)bit[i]+=val;
}
     
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",a+i),maxh=max(maxh,a[i]);
    LL ans=0;
    for(int i=n;i>=1;--i){
        ans+=sum(a[i]-1);
        update(a[i],1);
    }
    cout<<ans<<endl;
    return 0;
}

上一题