博客
关于我
P5367 【模板】康托展开
阅读量:229 次
发布时间:2019-02-28

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

为了求解给定全排列在所有全排列中的排名,我们采用康托展开和树状数组的方法。康托展开将问题分解为二进制位的处理,每个位的贡献累加即可得到逆序数。树状数组用于高效处理每个位的前缀和查询。

方法思路

  • 问题分析:计算一个排列的逆序数,即确定它在所有排列中的排名。
  • 康托展开:将每个数分解为二进制,每一位贡献的逆序数累加。
  • 树状数组:用于高效处理每个位的前缀和查询,确保算法在大数据下的高效性。
  • 解决代码

    MOD = 998244353def main():    import sys    n_and_rest = list(map(int, sys.stdin.read().split()))    n = n_and_rest[0]    a = n_and_rest[1:n+1]    max_n = n    size = 1    while size < max_n:        size <<= 1    size <<= 1    tree = [0] * (size + 2)    def update(idx, val):        while idx <= size:            tree[idx] = (tree[idx] + val) % MOD            idx += idx & -idx    def query(idx):        res = 0        while idx > 0:            res = (res + tree[idx]) % MOD            idx -= idx & -idx        return res    inv_size = [0] * (size + 2)    for i in range(size):        inv_size[i] = pow(size, MOD-2, MOD) * pow(i, MOD-2, MOD) % MOD    inv = [0] * (n + 2)    for i in range(n+1):        inv[i] = pow(i, MOD-2, MOD)    res = 0    for num in a:        power = 1        for k in range(30, -1, -1):            if num & (1 << k):                cnt = query(1 << k) - query(num & ((1 << k) - 1))                res = (res + cnt * power) % MOD                power = (power * 2) % MOD            else:                power = (power * 2) % MOD        update(num, 1)    print((res + 1) % MOD)if __name__ == "__main__":    main()

    代码解释

  • 初始化:读取输入,初始化树状数组和逆大小数组。
  • 更新和查询:定义树状数组的更新和前缀和查询函数。
  • 逆大小预处理:计算每个位置的逆大小,以便快速计算幂次。
  • 康托展开处理:遍历每个数,按位处理,计算每一位的贡献,更新结果。
  • 输出结果:输出最终结果,取模处理。
  • 该方法高效地处理了大规模数据,确保了算法在时间和空间上的可行性。

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

    你可能感兴趣的文章
    python_程序的构成---python工作笔记015
    查看>>
    python_超文本传输协议
    查看>>
    Python_集合
    查看>>
    Python|AsyncIO|TypeError:应为协程
    查看>>
    python——random模块的应用
    查看>>
    Python——基础知识细节
    查看>>
    Python——正则表达式
    查看>>
    Python—面向对象2
    查看>>
    Python“和“带整数的运算符
    查看>>
    Python“文件存在“制作目录时出错
    查看>>
    Python“文件存在“制作目录时出错
    查看>>
    Python、IMAP 和 GMail.将消息标记为已查看
    查看>>
    python一个一个获取迭代器的元素
    查看>>
    python一维数组 提取_python – 如何从numpy中的1维数组中提取零维切片
    查看>>
    python三大库之--numpy(一)
    查看>>
    python三大库之--numpy(二)
    查看>>
    python上的字无效字符_标识中的无效字符
    查看>>
    python下用decode和encode 中文转码
    查看>>
    Python下调用Linux的Shell命令
    查看>>
    Python接口自动化测试实战系列
    查看>>