Skip to content

M02299: Ultra-QuickSort

merge sort, http://cs101.openjudge.cn/practice/02299/

思路:问题等价于求逆序数,写一个递归函数即可,用时约25min(又去写bug去了)

cpp
#include <iostream>
#include <vector>
using namespace std;

long long merge_count(vector<long long>& a, int left, int right) 
{
    if (left >= right) return 0;
    int mid = (left + right) / 2;
    long long count = 0;
    count += merge_count(a, left, mid);
    count += merge_count(a, mid + 1, right);

    vector<long long> temp;
    int i = left, j = mid + 1;
    while (i <= mid && j <= right) 
    {
        if (a[i] <= a[j]) temp.push_back(a[i++]);
        else 
        {
            temp.push_back(a[j++]);
            count += (mid - i + 1); // 左边剩下的都比a[j]大
        }
    }
    while (i <= mid) temp.push_back(a[i++]);
    while (j <= right) temp.push_back(a[j++]);
    for (int k = 0; k < temp.size(); k++) 
        a[left + k] = temp[k];
    return count;
}

int main() 
{
    int n;
    while (cin >> n && n != 0) 
    {
        vector<long long> a(n);
        for (int i = 0; i < n; i++) cin >> a[i];
        long long ans = merge_count(a, 0, n - 1);
        cout << ans << "\n";
    }
    return 0;
}

思路:树状数组的模板题 (考试的时候把 solve 的返回值写成 int 了, 导致一直RE)

cpp
#include<bits/stdc++.h>
using namespace std;

class BIT {
private:
	long long n;
	vector<long long> tree;
	long long lowbit(long long n) {
		return n & -n;
	}
public:
	BIT(long long n) : n(n), tree(n + 1, 0) {};

	void update(long long idx, long long v=1) {
		for (long long i = idx; i <= n; i += lowbit(i)) {
			tree[i] += v;
		}
	}
	
	long long query(long long idx) {
		long long sum = 0;
		for (long long i = idx; i > 0; i -= lowbit(i)) {
			sum += tree[i];
		}
		return sum;
	}
};

void solve(long long n) {
	vector<long long> a(n);
	for (long long i = 0; i < n; i++) {
		cin >> a[i];
	}
	vector<long long> b = a;
	sort(b.begin(), b.end());
	BIT bit(n);
	
	long long ans = 0;
	for (long long i = 0; i < n; i++) {
		long long rank = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
		ans += i - bit.query(rank);
		bit.update(rank);
	}
	cout << ans << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

	while (1) {
		long long n;
		cin >> n;
		if (n == 0) break;
		solve(n);
	}
	return 0;
}