逆序对

设数列\(a\)\(N\)个元素。如果在\(i<j\)\(a_i>a_j\),则\((i,j)\)就称为\(a\)中的一个逆序对。求逆序对的数目。

#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 200000;
struct node {
  int v, id;
} b[maxn];
int a[maxn], c[maxn];
int N;
long long ans;

bool cmp(node x, node y) {
  if (x.v == y.v)
    return x.id < y.id;
  return x.v < y.v;
}

int lowbit(int i) { //返回i最低位的1 
  return i & -i;
}
int prefix_sum(int i) {
  int ans = 0;
  for (; i > 0; i -= lowbit(i))
    ans += c[i];
  return ans;
}
void add(int i, int x) {
  for (; i <= N; i += lowbit(i))
    c[i] += x;
}
int sum(int s, int t) {
  return prefix_sum(t) - prefix_sum(s - 1);
}

int main() {
  int i; 
  cin >> n;
  for (i = 0; i < N; i++) {
    cin >> b[i].v;
    b[i].id = i;
  }
  sort(b, b + N, cmp);
  int k = 1;
  a[b[0].id] = k;
  for (i = 1; i < N; i++) {
    if (b[i].v != b[i - 1].v)
      k++;
    a[b[i].id] = k;
    //a[i]中存储数组b从小到大去重排序后第i小的元素
  }
  for (i = 0; i < N; i++) {
    ans += sum(a[i], n);
    add(a[i], 1);
  }
  cout<< ans << endl;
  return 0;
}
posted @ 2017-08-17 20:15  Planet6174  阅读(191)  评论(0编辑  收藏  举报