当前位置: 代码迷 >> 综合 >> P1908 逆序对 Binary Indexed Tree(discretization)
  详细解决方案

P1908 逆序对 Binary Indexed Tree(discretization)

热度:101   发布时间:2023-10-09 13:59:58.0

题目描述

猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。最近,TOM老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中ai>aj且i<j的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。

输入输出格式

输入格式: 第一行,一个数n,表示序列中有n个数。 第二行n个数,表示给定的序列。 输出格式: 给定序列中逆序对的数目。

输入输出样例

输入样例#1:
6
5 4 2 6 3 1
输出样例#1:
11

说明

对于50%的数据,n≤2500 对于100%的数据,n≤40000。 题目思路: 输入数组的个数范围n<=40000,但是元素的大小a<=n并不成立。 对输入数据进行离散化操作。 离散化: 对于输入的数据(1,9999,2333,400)和(1,4,3,2)是没有区别的。我们把输入的数据大小和元素下标封装在一起A[i]中,根据数据大小进行排序,那么第一个数就是第一小,第二个就是第二小...由于之前封装了这个第一小的数字的位置,那么我们将这个位置填写为1,同理第二小的位置就写2....
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lowbit(x) ((x) & (-x))
using namespace std;
const int maxn = 40000 + 5;
int n, a[maxn], c[maxn], cnt[maxn];
void update(int x, int v) {
for (int i = x; i < maxn; i += lowbit(i)) {
c[i] += v;	
}
}
int getSum(int x) {
int sum = 0;
for (int i = x; i > 0; i -= lowbit(i)) {
sum += c[i];
}
return sum;
}
struct Node {
int val;
int id;
} A[maxn];
bool cmp(Node a, Node b) {
return a.val < b.val;
}
int main() {
scanf("%d", &n);
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++) {
scanf("%d", &A[i].val);
A[i].id = i;
}
long long ans = 0;
sort(A+1, A+1+n, cmp);
int b[maxn];
for (int i = 1; i <= n; ++i){
if (i == 1 || A[i].val != A[i-1].val) {
b[A[i].id] = i;	
} else {
b[A[i].id] = b[A[i-1].id];
}
}
for (int i = 1; i <= n; i++) {
update(b[i], 1);
// 左边元素个数 - 小于它的元素个数 = 大于它的元素个数
ans += (i - getSum(b[i]));
}
printf("%lld\n", ans);
return 0;
}


查看原文:http://iluhao.top/archives/616
  相关解决方案