逆序对

前置:归并排序

#include<bits/stdc++.h>
using namespace std;
const int N = 100005;
int n,a[N],b[N],ans = 0;
void mergesort(int l,int r){
	//只有一个数,不需要排列 
	if(l >= r) return;
	//计算中点,递归将两个子序排好 
	int mid = (l + r) / 2;
	mergesort(l,mid);
	mergesort(mid + 1,r);
	//两个指针p1,p2,分别指向两个序列的起始位置,注意合并至b数组 
	int p1 = l,p2 = mid + 1,p = l;
	while(p1 <= mid && p2 <= r){
		if(a[p1] < a[p2]){
			b[p] = a[p1];
			p++; p1++;
		}
		else{
			b[p] = a[p2];
			p++; p2++;
			ans += mid - p1 + 1;
		}
	}
	//解决数组末尾剩余部分,两个子序列可能都出现剩余,所以要扫尾 
	while(p1 <= mid){
		b[p] = a[p1];
		p++; p1++;
	}
	while(p2 <= r){
		b[p] = a[p2];
		p++; p2++;
	}
	//覆盖 
	for(int i = l;i <= r;i++)
		a[i] = b[i];
}
int main() {
    cin >> n;
    for (int i = 1;i <= n;i++)
        cin >> a[i];
    mergesort(1, n);
    for (int i = 1;i <= n;i++)
        cout << ans <<endl;
    return 0;
}


逆序对实现:

#include<bits/stdc++.h>
using namespace std;
const int N = 500005;
int n,a[N],b[N]; 
long long ans = 0;
inline int Read(){
  	char c = getchar();
  	int x = 0,f = 1;
  	while(c < '0' || c > '9'){
    	if(c == '-')
   		f = -1;
    	c = getchar();
  	}
  	while(c >= '0' && c <= '9'){
    	x = x * 10 + c - '0';
    	c = getchar();
  	}
  	return x * f;
}
void mergesort(int l,int r){
	//只有一个数,不需要排列 
	if(l >= r) return;
	//计算中点,递归将两个子序排好 
	int mid = (l + r) / 2;
	mergesort(l,mid);
	mergesort(mid + 1,r);
	//两个指针p1,p2,分别指向两个序列的起始位置,注意合并至b数组 
	int p1 = l,p2 = mid + 1,p = l;
	while(p1 <= mid && p2 <= r){
		if(a[p1] <= a[p2]){//注意注意注意 
			b[p] = a[p1];
			p++; p1++;
		}
		else{
			b[p] = a[p2];
			p++; p2++;
			ans += mid - p1 + 1;//注意注意注意 
		}
	}
	//解决数组末尾剩余部分,两个子序列可能都出现剩余,所以要扫尾 
	while(p1 <= mid){
		b[p] = a[p1];
		p++; p1++;
	}
	while(p2 <= r){
		b[p] = a[p2];
		p++; p2++;
	}
	//覆盖 
	for(int i = l;i <= r;i++)
		a[i] = b[i];
}
int main() {
	ios::sync_with_stdio(false);
	cout.tie(0);
    n = Read();
    for (int i = 1;i <= n;i++)
        a[i] = Read();
    mergesort(1, n);
    cout << ans << endl;
    return 0;
}
posted @ 2023-08-23 09:27  CultReborn  阅读(11)  评论(0)    收藏  举报