POJ2299 树状数组求逆序对

来源:互联网 发布:世界语言翻译软件 编辑:程序博客网 时间:2024/06/10 19:42

给定一个数组,求全部逆序对数目。

如果动态修改,如何求呢?


#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <algorithm>using namespace std;const int maxn= 500005;int aa[maxn];//离散化后的数组int c[maxn]; //树状数组int n;struct Node{    int v;    int order;}a[maxn];bool cmp(Node a, Node b){    return a.v < b.v;}int lowbit(int k){    return k&(-k); //基本的lowbit函数 }void update(int t, int value){     //即一开始都为0,一个个往上加(+1),    int i;    for (i = t; i <= n; i += lowbit(i))        c[i] += value;  }int getsum(int t){  //即就是求和函数,求前面和多少就是小于它的个数    int i, sum = 0;    for (i = t; i >= 1; i -= lowbit(i))        sum += c[i];    return sum;}int main(){    int i;    while (scanf("%d", &n), n)    {        for (i = 1; i <= n; i++) //离散化        {            scanf("%d", &a[i].v);            a[i].order = i;        }        sort(a + 1, a + n + 1,cmp);//从1到n排序,cmp容易忘        memset(c, 0, sizeof(c));        for (i = 1; i <= n; i++)            aa[a[i].order] = i;        __int64 ans = 0;        for (i = 1; i <= n; i++)        {            update(aa[i], 1);            ans += i - getsum(aa[i]); //减去小于的数即为大于的数即为逆序数        }        printf("%I64d\n", ans);    }    return 0;}