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;
}