目录
1.归并排序求逆序数
int InversePairsCore(vector<int>& data, vector<int>& copy, int begin, int end) {
if (begin == end)
return 0;
int mid = begin + (end - begin) / 2;
int low1 = begin, high1 = mid, low2 = mid + 1, high2 = end;
int left = InversePairsCore(copy, data, low1, high1);//这里的一步很绝啊,减少了数据交换的这一步
int right = InversePairsCore(copy, data, low2, high2);
long res = 0;
int copyIndex = low1;
// 归并排序:相当于两个有序数组合成一个有序表
//下面就开始两两进行比较,若前面的数大于后面的数,就构成逆序对
while (low1 <= high1 && low2 <= high2) {
if (data[low1] < data[low2]) {
copy[copyIndex++] = data[low1++];
}
else//data[low1] >= data[low2]
{
copy[copyIndex++] = data[low2++];
res += high1 - low1 + 1;
res %= 1000000007;
}
}
while (low1 <= high1)
copy[copyIndex++] = data[low1++];
while (low2 <= high2)
copy[copyIndex++] = data[low2++];
return (left + right + res) % 1000000007;
}
int InversePairs(vector<int> data) {
if (data.size() == 0)
return 0;
vector<int> copy(data); // 辅助数组,每次递归后有序
int res = InversePairsCore(data, copy, 0, data.size() - 1);
//for (int a : data) {
// cout << a << " ";
//}
//cout << endl;
//for (int a : copy) {
// cout << a << " ";
//}
//cout << endl;
return res;
}
2.树状数组求逆序数
树状数组可以求前缀和
#include <iostream>
using namespace std;
#include <vector>
#define lowbits(x) ((x) & (-x))
const int MAX = 8;
vector<int> a(MAX + 1, 0);
vector<int> BITree(MAX + 1, 0); //前缀和
void Update(int id, int new_data) { //维护数据
int temp = id;
int increse = new_data - a[id]; //获取修改结点的增量
while (temp <= MAX) {
BITree[temp] += increse; //对每个父节点都要修改增量
temp += lowbits(temp); //向前反推父节点直到根节点停止
}
}
int GetSum(int id) { //前缀和
int sum = 0; int temp_id = id;
while (temp_id > 0) {
sum += BITree[temp_id];
temp_id -= lowbits(temp_id);
}
return sum;
}
//int main(void) {
// for (int i = 1; i <= MAX; i++)
// Update(i, i);
// printf("区间[2,6]的和:%d", GetSum(6) - GetSum(2 - 1)); //求SubArr=GetSum[j]-GetSum[i-1]
// return 0;
//}
int main(void) {
int n;
cin >> n;
vector<int> v(n + 1, 0);
for (int i = 1; i <= n; i++) {
cin >> v[i];
if (v[i] == 1)
v[i] = -1;
else
v[i] = 1;
// cout << v[i] << ' ';
}
//vector<int> a(MAX + 1, 0);
//vector<int> BITree(n+1, 0);
for (int i = 1; i <=n; i++)
Update(i, v[i]);
for (int i = 1; i <=n; i++)
cout<<BITree[i]<<' ';
//printf("区间[2,6]的和:%d", GetSum(6) - GetSum(2 - 1)); //求SubArr=GetSum[j]-GetSum[i-1]
return 0;
}