• [树状数组]求排列的逆序数


    求排列的逆序数

    题目描述

    在Internet上的搜索引擎经常需要对信息进行比较,比如可以通过某个人对一些事物的排名来估计他(或她)对各种不同信息的兴趣,从而实现个性化的服务。

    对于不同的排名结果可以用逆序来评价它们之间的差异。考虑1,2,…,n的排列i1,i2,…,in,如果其中存在j,k,满足 j < k 且 ij > ik,那么就称(ij,ik)是这个排列的一个逆序。

    一个排列含有逆序的个数称为这个排列的逆序数。例如排列 263451 含有8个逆序(2,1),(6,3),(6,4),(6,5),(6,1),(3,1),(4,1),(5,1),因此该排列的逆序数就是8。显然,由1,2,…,n 构成的所有n!个排列中,最小的逆序数是0,对应的排列就是1,2,…,n;最大的逆序数是n(n-1)/2,对应的排列就是n,(n-1),…,2,1。逆序数越大的排列与原始排列的差异度就越大。

    现给定1,2,…,n的一个排列,求它的逆序数。

    输入

    第一行是一个整数n,表示该排列有n个数(n <= 100000)。
    第二行是n个不同的正整数,之间以空格隔开,表示该排列。

    输出

    输出该排列的逆序数。

    样例输入

    6
    2 6 3 4 5 1

    样例输出

    8

    提示

    1. 利用二分归并排序算法(分治);

    2. 注意结果可能超过int的范围,需要用long long存储。

     
    代码:
     1 #include<cstdio>
     2 const int Maxv = 100005;
     3 
     4 int c[Maxv], n;
     5 
     6 long long lb(int x) {
     7     return x & -x; 
     8 }
     9 void hs(int x, int p) {
    10     for (int i = x; i <= n; i += lb(i)) {
    11         c[i] += p;
    12     }
    13 }
    14 
    15 long long query(int x) {
    16       long long dl = 0;
    17       for (int i = x; i; i -= lb(i)) {
    18           dl += c[i];
    19     }
    20       return dl;
    21 }
    22  
    23 int main(){
    24     long long ans = 0;
    25     scanf("%d", &n);
    26     for (int i = 1; i <= n; i++){   
    27         int a;
    28         scanf("%d", &a); 
    29         hs(a, 1);         
    30         ans += i - query(a);        
    31     }
    32     printf("%lld
    ", ans);
    33     return 0;
    34 }
  • 相关阅读:
    【C#】最完整的IIS添加WCF配置
    IIS配置中增加对WCF程序的支持svc(IIS10中添加WCF支持几种方法小结)
    ASP.NET C#各种数据库连接字符串大全——SQLServer、Oracle、Access
    记一次 .NET 某医院HIS系统 CPU爆高分析(Windbg)
    C#调用Win32 API 的方法
    闲无聊,发个winform中使用html编辑器的方案
    使用非托管 DLL 函数
    flask中的CBV和FBV
    2.6 CSS3其他特性(了解)
    2.5 CSS3盒子模型
  • 原文地址:https://www.cnblogs.com/GldHkkowo/p/8849022.html
Copyright © 2020-2023  润新知