zoukankan      html  css  js  c++  java
  • poj2299树状数组入门,求逆序对

    今天入门了树状数组 习题链接 https://blog.csdn.net/liuqiyao_01/article/details/26963913

    离散化数据:用一个数组来记录每个值在数列中的排名,不能用map,会超时

    开结构体存储每个数在数列中原来的位置,排序后用a数组求出原来状态下每个数的排名。

    /*
    线段树求逆序对的话是按顺序把数字插到数字对应的线段树下标里,然后统计该下标右边的数个数
    树状数组求逆序对思路:按顺序一个个插到数组中,统计比它小的个数,逆序数=当前数的下标-当前比它小的个数
    
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define maxn 500500
    #define ll long long
    using namespace std;
    struct node{
        int val,pos;
        bool operator<(const node & a)const {
            return val<a.val;
        }
    }p[maxn];
    int n,bit[maxn],a[maxn];
    //树状数组bit[i]维护的信息是排名在一个区间内的数字个数
    //数组a表示第i个数的排名是多少
    void add(int i){
        while(i<=n){
            bit[i]+=1;
            i+=i&-i;
        }
    }
    int sum(int i){
        int s=0;
        while(i>0){
            s+=bit[i];
            i-=i&-i;
        }
        return s;
    }
    void solve(){
        for(int i=1;i<=n;i++){scanf("%d",&p[i].val);p[i].pos=i;}
        sort(p+1,p+1+n);
        for(int i=1;i<=n;i++)a[p[i].pos]=i;
        memset(bit,0,sizeof bit);
        ll ans=0;
        for(int i=1;i<=n;i++){
            add(a[i]);//排名为a[i]的地方加1
            ans+=i-sum(a[i]);//当前所有被加入的数个数-排名在第i的数之前的数=增加的逆序对数
        }
        printf("%lld
    ",ans);
    }
    int main(){
        while(scanf("%d",&n),n)solve();
    }
  • 相关阅读:
    Python-枚举
    Python-函数
    Python-装饰器(语法糖)上下五千年和前世今生
    Python-全局函数(内置方法、内置函数)
    Python-时间模块-time
    Python-随机模块-random
    Python-维护排序好的序列模块-bisect
    需求推动技术的产生
    RBF神经网络
    聚类算法的衡量指标
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10073906.html
Copyright © 2011-2022 走看看