POJ 2299

来源:互联网 发布:丽水网络图书馆 编辑:程序博客网 时间:2024/05/22 04:52

求逆序数,实际上有多种方法,枚举法,插入排序法,冒泡排序算法,归并排序算法,树状数组等方法都可以求解逆序数,前三种当数据比较多时效率比较低,由于数据比较大因此利用树状数组求解时可以把原来数组离散化!

离散化:

9999999 66666666 5555 777777     ··············(1)

1          2      3     4        ··············(2)

序列(2)是序列(1)的下表;当对(1)排序后可知序列(2)的排列状态为(2‘): 3  4 1 2 ,因此求原序列(1)的逆序数,就是求序列(2’)的逆序数,处理起来比较方便!

一下有两种求解方法,第一个代码是归并排序算法求解,另一个为树状数组求解,仅供参考!

//归并排序来求解逆序数,记得不能全部初始化,否则会超时!#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const int MAXN = 500000;int a[MAXN], b[MAXN];LL sum ;void Merge(int low, int mid, int high){    //memset(b, 0, sizeof(b));    int i = low, j = mid+1, k = low;    while(i <= mid && j <= high)    {        if(a[i] <= a[j])            b[k++] = a[i++];        else            b[k++] = a[j++], sum += (mid - i+1);    }    while(i <= mid)        b[k++] = a[i++];    while(j <= high)        b[k++] = a[j++];    for(i = low; i <= high; ++i)        a[i] = b[i];    return ;}void Merge_Sort(int low, int high){    if(low == high)        return ;    if(low < high)    {        int mid = (low + high) >> 1;        Merge_Sort(low, mid);        Merge_Sort(mid+1, high);        Merge(low, mid, high);    }}int main(){    int n, i;    while(~scanf("%d", &n) && n)    {        //memset(a, 0, sizeof(a));        for(i = 0; i < n; ++i)            scanf("%d", &a[i]);        sum = 0;        Merge_Sort(0, n-1);        printf("%I64d\n", sum);    }    return 0;}

树状数组:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MAXN = 500000;typedef long long LL;int a[MAXN], c[MAXN];struct Node{    int index;    int num;    Node()    {        index = 0;        num = 0;    }}Tree_arr[MAXN];/**int cmp(const void* a, const void* b){    Node* aa = (Node *)a;    Node* bb = (Node *)b;    return aa->num - bb->num;}*/bool cmp(Node a, Node b){    return a.num < b.num;}int LowBit(int x){    return x & (-x);}void UFset(int n, int pos, int num){    while(pos <= n)    {        c[pos] += num;        pos += LowBit( pos );    }}int Query(int pos, int sum){    while(pos > 0)    {        sum += c[pos];        pos -= LowBit( pos );    }    return sum;}int main(){    int n;    LL sum;    while(~scanf("%d", &n) && n)    {        for(int i = 1; i <= n; ++i)        {            scanf("%d", &Tree_arr[i].num);            Tree_arr[i].index = i;        }        //qsort(Tree_arr+1, n, sizeof(Tree_arr[0]), cmp);        sort(Tree_arr+1,Tree_arr+n+1, cmp);        for(int i = 1; i <= n; ++i)            a[Tree_arr[i].index] = i;        memset(c, 0, sizeof(c));        sum = 0;        for(int i = 1; i <= n; ++i)        {            UFset(n, a[i], 1);            sum += a[i] - Query(a[i], 0);        }        printf("%I64d\n", sum);    }    return 0;}


0 0
原创粉丝点击