【逆序对 冒泡sort】 Ultraquick sort

传送门

题意

该排序算法通过交换两个相邻的序列元素处理\(n\)个不同整数的序列,直到序列升序排列,确定超快速排序需要交换多少次

数据范围

\(\begin{array}{l}0 \leq N<500000 \\ 0 \leq a_{i} \leq 999999999\end{array}\)

题解

只交换相邻数值的方法排序是冒泡排序,排序过程中每找到一组逆序的相邻值进行交换,
这样会使得整个序列中的逆序对个数\(-1\),所以最终排好序以后,逆序对个数为\(0\)
所以对\(a\)进行冒泡排序需要的最少交换次数就是序列\(a\)中逆序对的个数

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first
#define se second 
#define ll long long
#define pb push_back
#define close ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);


typedef pair<long long,long long> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<long long> vll;
typedef double db;


const ll mod=1e9+7;
const int N=1e6+10;

ll powmod(ll a,ll b,ll p)
{
    ll res=1;
    a%=p;
    while(b)
    {
        if(b&1) res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
ll gcd(ll a,ll b) 
{
    return b?gcd(b,a%b):a;
}


int _;
int n;
int a[N];
int ans[N];
ll merge_sort(int l,int r){
    if(l>=r) return 0;
    int mid=l+r>>1;
    ll res=merge_sort(l,mid)+merge_sort(mid+1,r);

    int k = 0,i = l,j = mid+1;
    while(i <= mid && j <= r){
        if(a[i] <= a[j])
            ans[k++]=a[i++];
        else{
            ans[k++]=a[j++];
            res+=mid-i+1;
        }
    }
    while(i <= mid) ans[k++] = a[i++];
    while(j <= r) ans[k++] = a[j++];

    for(int i = l,j = 0; i <= r; i++,j++)
        a[i]=ans[j];
    return res;
}
void solve()
{
    for(int i=0;i<n;i++)
            cin>>a[i];

    cout<<merge_sort(0,n-1)<<endl;
}
int main(){
    close;
    while(cin>>n&&n) solve();
}
posted @ 2020-09-21 22:20  Hyx'  阅读(110)  评论(0)    收藏  举报