【逆序对 冒泡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();
}

浙公网安备 33010602011771号