链接:https://www.nowcoder.com/acm/contest/77/A
来源:牛客网
题目描述
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。比如一个序列为4 5 1 3 2, 那么这个序列的逆序数为7,逆序对分别为(4, 1), (4, 3), (4, 2), (5, 1), (5, 3), (5, 2),(3, 2)。
输入描述:
第一行有一个整数n(1 <= n <= 100000), 然后第二行跟着n个整数,对于第i个数a[i],(0 <= a[i] <= 100000)。
输出描述:
输出这个序列中的逆序数
示例1
输入
5 4 5 1 3 2
输出
7
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 0x3f3f3f3f; const int moder = 10000; const int maxn = 2000000; int d[100010]; int n; int a[100010]; int lowbit(int x) { return x&(-x); } int query(int x) { int res = 0; while(x) { res += d[x]; x -= lowbit(x); } return res; } void add(int x,int v) { while(x <= n) { d[x] += v; x += lowbit(x); } } int main() { cin >> n ; memset(d,0,sizeof(d)); for(int i=1;i <= n;i++) { scanf("%d",&a[i]); } ll ans = 0; for(int i=1;i <= n;i++) { add(a[i],1); //逐个将数组中的数字出现的地方标记为1,用来求前缀和。 ans += i - query(a[i]);//一开始不是很好理解为什么这样写,自己举一些列子就明白了,i 是不断增加的,如果a[i]前没有比他大的说明他是目前最小的,即之前输入的数都能喝他构成逆序对。 } printf("%lld\n",ans); return 0; }
——