树状数组基础引入:BZOJ 1266 计算逆序对问题

本文介绍了如何使用二路归并和树状数组解决逆序对问题。通过实例解析了二路归并的实现,然后详细讲解了树状数组的应用,包括离散化的过程,并提供了两种离散化方法的代码实现。最后,讨论了树状数组在解决冒泡排序最少交换次数问题中的应用,并总结了树状数组的重要性和学习价值。
摘要由CSDN通过智能技术生成

目录

一.题目

题目描述

输入

输出

样例输入

样例输出

题解

     二路归并

    树状数组

举一反三

总结


一.题目


题目描述

      设A[1..n]是一个包含N个数的数组。如果在i〈 j的情况下,有A[i] 〉a[j],则(i,j)就称为A中的一个逆序对。 例如,数组(3,1,4,5,2)的“逆序对”有 <3,1>,<3,2>,<4,2>,<<5,2> 共4个。 使用 归并排序 可以用O(nlogn)的时间解决统计逆序对个数的问题 。

输入

      第1行:1个整数N表示排序元素的个数。(1≤N≤100000) 第2行:N个用空格分开的整数,每个数在小于100000。

输出

      1行:仅一个数,即序列中包含的逆序对的个数。

样例输入

3

1 3 2

样例输出

1


题解

      这是一道十分简单的树状数组引入题目。相信大家一定都做过逆序对吧,首先来看二路归并的代码:

     


二路归并

            十分简单,只要会二分排序,那么就一定会这道题:

            代码如下:

#include <cstring>
#include <cstdio>
#define M 100005
int n, a[M], b[M], c[M];
long long ans;
inline void bing(int l, int mid, int r){
    int k = l, k1 = mid + 1, k2 = l;
    while(k <= mid && k1 <= r){
        if(a[k] <= a[k1])
            b[k2 ++] = a[k ++];
        else{
            ans = ans + mid - k + 1;
            b[k2 ++] = a[k1 ++];
        }
    }
    while(k <= mid) 
        b[k2 ++] = a[k ++];
    while(k1 <= r)
        b[k2 ++] = a[k1 ++];
    for(int i = l; i <= r; i ++)
        a[i] = b[i];
}
inline void fen(int l, int r){
    int mid = (l + r) / 2;
    if(l >= r)
        return ;
    fen(l, mid);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值