zoukankan      html  css  js  c++  java
  • 三部曲一(数据结构)-1020-Ultra-QuickSort

    通过这道题我大体理解了树状数组的原理和用法,完全用的别人的算法,我把别人算法看懂之后有自己敲了一遍,不得不说这算法真是高深巧妙啊,我开始看都看不懂,还是在别人的讲解下才看懂的,我觉得有必要写个博客记录一下。

    算法先将所有数字离散化,按原来的大小关系从1一直到n。开始c数组的值全为零,每次插入一个数就将那一位的数组加一,并记录它和它前面的的数的和,即正序数+1,求得正序数之后,已插入的数的个数减去sum就是逆序数,最后把所有逆序数的和加起来,如一组数列

    7 2 8 3 5

    依次插入各个数

    开始    0 0 0 0 0 0 0 0

    插入7  0 0 0 0 0 0 1 0 sum=1 sum_reverse=0

    插入2  0 1 0 0 0 0 1 0 sum=1 sum_reverse=1

    插入8  0 1 0 0 0 0 1 1 sum=3 sum_reverse=0 

    插入3  0 1 1 0 0 0 1 1 sum=2 sum_reverse=2

    插入5  0 1 1 0 1 0 1 1 sum=3 sum_reverse=2

    求得逆序数为5

    具体实现用树状数组,实现,每次插入一个数都要更新它上面的数。

    代码如下

    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int b[500001],c[500001],n;
    
    struct node
    {
        int val,id;
    }num[500001];
    
    bool cmp(const node n1,const node n2)
    {
        return  n1.val<n2.val;
    }
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    int update(int i,int x)
    {
        while(i<=n)
        {
            c[i]+=x;
            i+=lowbit(i);
        }
    }
    
    int sum(int i)
    {
        int s=0;
        while(i>0)
        {
            s+=c[i];
            i-=lowbit(i);
        }
        return s;
    }
    
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int i;
        long long ans;
        while(scanf("%d",&n)!=EOF&&n)
        {
            memset(b,0,sizeof(b));
            memset(c,0,sizeof(c));
            for(i=0;i<n;i++)
            {
                scanf("%d",&num[i].val);
                num[i].id=i;
            }
            sort(num,num+n,cmp);
            b[num[0].id]=1;
    //        for(i=0;i<n;i++)
    //            cout<<num[i].id<<' ';
    //        cout<<endl;
            for(i=1;i<n;i++)
            {
                if(num[i].val!=num[i-1].val)
                    b[num[i].id]=i+1;
                else
                    b[num[i].id]=b[num[i-1].id];
            }
    ////        for(i=0;i<n;i++)
    ////            cout<<b[i]<<' ';
    ////        cout<<endl;
            ans=0;
            for(i=0;i<n;i++)
            {
                update(b[i],1);
                ans+=(sum(n)-sum(b[i]));
    
            }
            printf("%I64d
    ",ans);
        }
    }
    

      

  • 相关阅读:
    204. Count Primes (Integer)
    203. Remove Linked List Elements (List)
    202. Happy Number (INT)
    201. Bitwise AND of Numbers Range (Bit)
    200. Number of Islands (Graph)
    199. Binary Tree Right Side View (Tree, Stack)
    198. House Robber(Array; DP)
    191. Number of 1 Bits (Int; Bit)
    190. Reverse Bits (Int; Bit)
    189. Rotate Array(Array)
  • 原文地址:https://www.cnblogs.com/aljxy/p/3439116.html
Copyright © 2011-2022 走看看