蓝桥杯备赛 Day8.2求逆序对

信息学奥赛一本通(C++版)在线评测系统

【题目描述】

给定一个序列a1,a2,…,ana1,a2,…,an,如果存在iajai>aj,那么我们称之为逆序对,求逆序对的数目。

【输入】

第一行为nn,表示序列长度,接下来的nn行,第i+1i+1行表示序列中的第ii个数。

【输出】

所有逆序对总数。

 代码解答     

#include
#define int long long
using namespace std;

//暴力超时
//const int N = 1e5 + 10;
//int a[N];
//int main() {
//	int n; cin >> n;
//	for (int i = 1; i <= n; i++) cin >> a[i];
//	int ans = 0;
//	for (int i = 1; i <= n; i++) {
//		for (int j = i+1; j <= n; j++) {
//			if (a[i] > a[j])ans++;
//		}
//	}
//	cout << ans;
//	return 0;	
//}

//归并排序
//2.合并+排序 
int ans;
void merge_sort(int a[], int l, int mid, int r) {
	int* t = new int[r - l + 1];
	int i = l, j = mid + 1;
	int id = 0;
	while (i <= mid && j <= r) {
		if (a[i] <= a[j]) t[id++] = a[i++];
		else {//a[i] > a[j]
			ans += mid - i + 1;
			t[id++] = a[j++];
		}
	}
	while (i <= mid)  t[id++] = a[i++];
	while (j <= r) t[id++] = a[j++];
	for (int i = 0; i < id; i++)
		a[i + l] = t[i];
	delete[]t;
}

//1.自顶向下分解 
void merge_up2down(int a[], int l, int r) {
	if (l >= r) return;
	int mid = l + r >> 1;
	merge_up2down(a, l, mid);
	merge_up2down(a, mid + 1, r);
	merge_sort(a, l, mid, r);
}

const int N = 1e5 + 10;
int n, a[N];
signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> a[i];
	merge_up2down(a, 1, n);
	//for(int i=1;i<=n;i++) cout<

                                                                          

你可能感兴趣的:(蓝桥杯,算法)