参考代码:
使用的是归并排序
52分的代码:
#include
#include
#include
using namespace std;
long long merge(vector
int i = start;
int j = mid + 1;
int k = start;
long long count = 0;
while (i <= mid && j <= end) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
count += mid - i + 1;
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= end) {
temp[k++] = arr[j++];
}
for (int l = start; l <= end; l++) {
arr[l] = temp[l];
}
return count;
}
long long mergeSort(vector
if (start >= end) {
return 0;
}
int mid = start + (end - start) / 2;
long long count = 0;
count += mergeSort(arr, temp, start, mid);
count += mergeSort(arr, temp, mid + 1, end);
count += merge(arr, temp, start, mid, end);
return count;
}
int main() {
int n;
cin >> n;
vector
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
vector
long long inversionCount = mergeSort(arr, temp, 0, n - 1);
cout << inversionCount << endl;
return 0;
}
我以为可以在归并排序的基础上进行优化一下就可以过了,然后就是62分,76分
然后看了一下题解,说要用BIT(树状数组)进行解题才不会时间超限
第一次的BIT(树状数组)就是90分,然后优化一下才过了
第一次的BIT,90分的参考代码:
#include
#include
#include
using namespace std;
// 树状数组类
class BIT {
public:
BIT(int size) : bit(size + 1, 0) {}
// 更新指定位置的计数
void update(int index, int delta) {
while (index < bit.size()) {
bit[index] += delta;
index += lowbit(index);
}
}
// 获取指定位置的前缀和
int query(int index) {
int sum = 0;
while (index > 0) {
sum += bit[index];
index -= lowbit(index);
}
return sum;
}
private:
vector
// 计算最低位的1的位置
int lowbit(int x) {
return x & (-x);
}
};
int main() {
int n;
cin >> n;
vector
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
// 离散化,通过排序得到每个元素在排序后的序列中的位置
vector
sort(sortedArr.begin(), sortedArr.end());
for (int i = 0; i < n; i++) {
arr[i] = lower_bound(sortedArr.begin(), sortedArr.end(), arr[i]) - sortedArr.begin() + 1;
}
// 创建树状数组
BIT bit(n);
long long count = 0;
// 从右往左遍历离散化后的数组
for (int i = n - 1; i >= 0; i--) {
count += bit.query(arr[i] - 1); // 获取比当前元素小的元素的计数
bit.update(arr[i], 1); // 当前元素出现一次,更新计数
}
cout << count << endl;
return 0;
}
最后的AC代码:(多提交几次就过了)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 树状数组类
class BIT {
public:
BIT(int size) : bit(size + 1, 0) {}
// 更新指定位置的计数
void update(int index, int delta) {
while (index < bit.size()) {
bit[index] += delta;
index += lowbit(index);
}
}
// 获取指定位置的前缀和
int query(int index) {
int sum = 0;
while (index > 0) {
sum += bit[index];
index -= lowbit(index);
}
return sum;
}
private:
vector<int> bit;
// 计算最低位的1的位置
int lowbit(int x) {
return x & (-x);
}
};
int main() {
int n;
cin >> n;
vector<int> arr(n);
vector<pair<int, int>> values(n);
for (int i = 0; i < n; i++) {
cin >> arr[i];
values[i] = make_pair(arr[i], i);
}
// 按照键排序
sort(values.begin(), values.end());
// 创建重映射数组
vector<int> mapping(n);
for (int i = 0; i < n; i++) {
mapping[values[i].second] = i + 1;
}
// 创建树状数组
BIT bit(n);
long long count = 0;
// 从右往左遍历原始数组
for (int i = n - 1; i >= 0; i--) {
int pos = mapping[i]; // 获取当前元素在排序后的序列中的位置
count += bit.query(pos - 1); // 获取比当前元素小的元素的计数
bit.update(pos, 1); // 当前元素出现一次,更新计数
}
cout << count << endl;
return 0;
}
0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复