博客
关于我
P1908 逆序对(树状数组)
阅读量:707 次
发布时间:2019-03-21

本文共 2138 字,大约阅读时间需要 7 分钟。

对于逆序对的计算,可以借助树状数组(BIT)来高效解决问题。树状数组是一种数据结构,专门用于处理前缀和查询等操作,非常适合逆序对计数的问题。以下是对该问题的详细分析和解决方法:

首先,理解逆序对的定义:逆序对是指在数组中,i < j 且 a[i] > a[j]。计算逆序对的数量在数据处理领域是一个常见问题,传统的双重循环算法在数据量较大时显然效率低下。树状数组可以在这种问题上实现时间复杂度的优化。

核心思想

  • 离散化(Coordinate Compression):由于数组元素可能非常大,直接使用数组索引无法处理,因此需要将原始数值映射到较小的范围内。如何离散化是关键:

    • 将数组中的元素(unique后)按顺序排列,分配给它们新的id,确保相同的数值得到相同的id。
    • 在比较两个元素时,先比较它们的新id,这样离散化后的数据保持了原来的相对顺序。
  • 树状数组的应用

    • 更新操作:在树状数组中记录元素出现的位置。
    • 查询操作:通过树状数组计算前缀和,从而统计逆序对的数量。
  • 详细步骤

  • 离散化过程

    • 将数组中的元素收集起来,去重,并按照从小到大的顺序排列。
    • 为每个唯一元素分配一个新的id,id的顺序与元素的原顺序一致。例如,元素1、3、5映射到id1、id2、id3。
  • 树状数组的初始化

    • 确定离散化后的最大id,然后初始化一个数组tree,大小为当前最大id的两倍,确保 suf(最低有效位)为1。
  • lowbit函数

    • used to determine the next position in the tree for update or query operations.
    • 该函数通过位运算快速找到下一个树状数组的位置,即pos += lowbit(pos)。
  • 更新操作

    • 每次遇到一个元素,调用update函数,将其位置记录到树状数组中。例如,当处理5时,update函数会在id3位置增加计数。
  • 查询操作

    • 为了计算逆序对的数量,按顺序处理每个元素。针对元素a[j],统计前面已经处理的元素中id大于当前元素id的数量,这部分的数量即为与a[j]形成逆序对的数量。
    • 使用query函数获取前缀和,统计满足条件的逆序对数目。
  • 逆序对计算

    • 最终的答案为总组合数减去非逆序对数。例如,示例数组中有5个元素,总共有C(5,2)=10个组合,其中7个是非逆序对,答案是10-7=3个逆序对。
  • 树状数组的实现

    # 树状数组实现def init(max_n):    return [0] * (max_n + 2)def update(tree, index, value):    while index <= max_n:        tree[index] += value        index += lowbit(index)def query(tree, index):    res = 0    while index > 0:        res += tree[index]        index -= lowbit(index)    return resdef query_range(tree, l, r):    return query(tree, r) - query(tree, l - 1)

    代码示例

    def main():    n = len(arr)    sorted_unique = sorted(list(set(arr)))    # 创建映射字典,将每个元素映射到最小的id    id_map = {v: i + 1 for i, v in enumerate(sorted_unique)}    max_id = max(id_map.values())        tree_size = max_id * 2    tree = init(tree_size)        for num in arr:        id_num = id_map[num]        update(tree, id_num, 1)            res = 0    for i in reversed(range(n)):        num = arr[i]        current_id = id_map[num]        res += query(tree, current_id - 1)    return res

    注意事项

    • 优化树状数组大小:确保树状数组足够大以容纳所有最大id。
    • 离散化时的排序:离散化时,排序后的元素顺序必须保持原始数组的顺序,只有当元素相同时才能分配相同的id。
    • 处理重复元素:确保在离散化过程中,重复的元素被映射到该在排序中的正确位置,这样它们会被视为非逆序对。

    总结

    通过离散化和树状数组,可以高效地解决逆序对问题。树状数组的更新和查询操作确保了时间复杂度的优化,这使得问题可以处理非常大的数组。关键是正确实现离散化步骤,保证数据的相对顺序,避免错误地计算逆序对数量。这种方法不仅适合逆序对的问题,还能扩展到其他需要频繁查询和更新操作的场景。

    转载地址:http://zsjrz.baihongyu.com/

    你可能感兴趣的文章
    NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
    查看>>
    nifi使用过程-常见问题-以及入门总结---大数据之Nifi工作笔记0012
    查看>>
    NIFI分页获取Mysql数据_导入到Hbase中_并可通过phoenix客户端查询_含金量很高的一篇_搞了好久_实际操作05---大数据之Nifi工作笔记0045
    查看>>
    NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    NIFI同步MySql数据源数据_到原始库hbase_同时对数据进行实时分析处理_同步到清洗库_实际操作06---大数据之Nifi工作笔记0046
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_FlowFile拓扑_对FlowFile内容和属性的修改删除添加_介绍和描述_以及实际操作---大数据之Nifi工作笔记0023
    查看>>
    NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_处理器介绍_处理过程说明---大数据之Nifi工作笔记0019
    查看>>
    NIFI大数据进阶_FlowFile生成器_GenerateFlowFile处理器_ReplaceText处理器_实际操作---大数据之Nifi工作笔记0020
    查看>>
    NIFI大数据进阶_Json内容转换为Hive支持的文本格式_实际操作_02---大数据之Nifi工作笔记0032
    查看>>
    NIFI大数据进阶_Json内容转换为Hive支持的文本格式_操作方法说明_01_EvaluteJsonPath处理器---大数据之Nifi工作笔记0031
    查看>>
    NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka消费者处理器_来消费kafka数据---大数据之Nifi工作笔记0037
    查看>>
    NIFI大数据进阶_Kafka使用相关说明_实际操作Kafka生产者---大数据之Nifi工作笔记0036
    查看>>
    NIFI大数据进阶_NIFI的模板和组的使用-介绍和实际操作_创建组_嵌套组_模板创建下载_导入---大数据之Nifi工作笔记0022
    查看>>
    NIFI大数据进阶_NIFI监控功能实际操作_Summary查看系统和处理器运行情况_viewDataProvenance查看_---大数据之Nifi工作笔记0026
    查看>>
    NIFI大数据进阶_NIFI监控的强大功能介绍_处理器面板_进程组面板_summary监控_data_provenance事件源---大数据之Nifi工作笔记0025
    查看>>
    NIFI大数据进阶_NIFI集群知识点_认识NIFI集群以及集群的组成部分---大数据之Nifi工作笔记0014
    查看>>
    NIFI大数据进阶_NIFI集群知识点_集群的断开_重连_退役_卸载_总结---大数据之Nifi工作笔记0018
    查看>>
    NIFI大数据进阶_使用NIFI表达式语言_来获取自定义属性中的数据_NIFI表达式使用体验---大数据之Nifi工作笔记0024
    查看>>