zoukankan      html  css  js  c++  java
  • 求逆序数——树状数组

    简介

      首先解释一下什么是逆序数,在一个排列中,如果前面的数大于后面的数,则称这两个数为一对逆序,而在这个排列中逆序对的总数称为逆序数。

      然后对于树状数组,如果有一点了解的话,树状数组一般是用于数组区间求和,加单点修改的一种数据结构。如果不了解,可以去百度一下。

    思路

      我们要求逆序数,不能直接针对这个排列进行树状数组的添加和求和,这样也没有意义。

      我们需要对于排列中的每一个数是否出现进行树状数组的操作。用一个数组vis,vis[i]=1表示i在这个排列中,为0就表示不存在。

      那我们遍历一遍排列,对于出现的每一个数,我们进行树状数组的添加,加一。表示这个数出现在排列中了。而如果求和的操作,即表示求在当前位置之前比这个数小的数目。

      那i-sum(a)即表示大于这个数的数目,i是当前数的位置,a表示这个数。

    代码

      

    #include <bits/stdc++.h>
    using namespace std;
    int num[100005];
    int n=100005;
    int lowbit(int i){
        return i&-i;
    }
    void add(int x,int y){
        for(int i=x;i<n;i+=lowbit(i)){
            num[i]+=y;
        }
    }
    int sum(int x){
        int ans=0;
        while(x>0){
            ans+=num[x];
            x-=lowbit(x);
        }
        return ans;
    }
    int main()
    {
        int m;
        while(cin>>m){
            int a;
            long long ans=0;
            for(int i=1;i<=m;i++){
                cin>>a;
                add(a,1);
                ans+=i-sum(a);
            }
            cout<<ans<<endl;
        }
        return 0;
    }

     题目来源:https://ac.nowcoder.com/acm/problem/15163

  • 相关阅读:
    混杂模式
    消息队列学习
    item21
    消息队列改写
    socket select模型
    EffectiveC++ Item11
    How to read a PCap file from Wireshark with C++
    winsock select学习
    线程安全与可重入函数
    process explorer 查看句柄或者加载的dll
  • 原文地址:https://www.cnblogs.com/maybe96/p/10300330.html
Copyright © 2011-2022 走看看