逆序数算法

article/2025/9/22 5:27:29

原题

在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
如2 4 3 1中,2 1,4 3,4 1,3 1是逆序,逆序数是4。给出一个整数序列,求该序列的逆序数。

输入

1行:N,N为序列的长度(n <= 50000)2 - N + 1行:序列中的元素(0 <= A[i] <= 10^9

输出

输出逆序数

输入样例

4
2
4
3
1

输出样例

4

开始分析
不知道大家有没有写过二路归并排序的题目。如果做过那么接下来你看起来就会很简单。否则会很吃力。

在这里放一个左神讲解这些题目的一个连接,想看的可以看一下。时间比较长。
连接

二路归并排序代码

#include <iostream>
using namespace std;void merge(int arr[],int l,int mid,int r){int help[r-l+1];int i = 0;int p1 = l;int p2 = mid+1;while(p1 <= mid&&p2 <= r){help[i++] = arr[p1] <= arr[p2] ? arr[p1++]:arr[p2++];}while(p1 <= mid){help[i++] = arr[p1++];}while(p2 <= r){help[i++] = arr[p2++];}for(i = 0;i < r-l+1;i++){arr[l+i] = help[i];}
}void process(int arr[],int l,int r){if(l == r){return ;}int mid = l+((r-l)>>1);process(arr,l,mid);process(arr,mid+1,r);merge(arr,l,mid,r);
}int main(void){int arr[] = {2,3,7,8,1,23,67,99,2,4,7,8,10};int len = sizeof(arr)/sizeof(arr[0]);process(arr,0,len-1);for(int i = 0;i < len;i++){cout<<arr[i]<<" ";}return 0;
} 

不知道大家看没看我刚才给大家的二路归并排序算法。我的逆序数算法就是在这个的基础上多加了几行代码罢了。

我们先拿一个简单的例子:

arr[] = {3,5,7,2,4,6};

以这个数组为例子,开始讲解。

  1. 我们先把这个数组给他拆成两份。开始各自排序。
  2. 如果数组中只有一个数字时直接返回,此时必定是有序的。
  3. 如果两边的数组已经排序完毕(此时各自都是有序的),开始merge。

那么最终返回的必定是有序的数组。

那么我们的改动就是在第三步,即merge的时候,计算一下逆序的数字就可以了。
在这里插入图片描述

  1. 如果arr1[p1] > arr[p2],那么说明产生了逆序数。在这里需要计数。
  2. 值得注意的一点是,如果p1位置数字是大于的,那么p1+1,p1+2…位置的数字也是大于p2位置的数字的(因为是有序的)。
  3. 所以计数的时候需要注意,计数时需要计从p1到左边数组的末尾的长度。

代码就是这样:

#include <bits/stdc++.h>
using namespace std;
//逆序数--可以用小和问题的思路来解题
//即采用二路归并排序const int N = 50000;
int arr[N];int merge(int arr[],int l,int mid,int r){int help[r-l+1];int p1 = l;int p2 = mid+1;int i = 0;int sum = 0;while(p1 <= mid&&p2 <= r){if(arr[p1] < arr[p2]){help[i++] = arr[p1++];}else if(arr[p1] > arr[p2]){help[i++] = arr[p2++];//此时有逆序数 sum += mid-p1+1;}else{help[i++] = arr[p2++];}}while(p1 <= mid){help[i++] = arr[p1++];}while(p2 <= r){help[i++] = arr[p2++];}i = 0;for(p1 = l;p1 < p2;p1++){arr[p1] = help[i++];}return sum;
}int process(int arr[],int l,int r){if(l == r){//此时数组中只有一个数字//因此就不存在逆序数了return 0; }int mid = l + ((r - l)>>1);int sum = 0;int end = process(arr,l,mid);
//	cout<<end<<endl;sum = end;end = process(arr,mid+1,r);
//	cout<<end<<endl;sum += end;return sum+merge(arr,l,mid,r);
}int main(void){int n;cin>>n;int i = 0;for(;i < n;i++){cin>>arr[i];}int sum = process(arr,0,n-1);cout<<sum<<endl;return 0;
}

http://chatgpt.dhexx.cn/article/YEVn2ORe.shtml

相关文章

C语言计算逆序数

从键盘任意输入一个3为整数&#xff0c;编程计算并输出它的逆序数&#xff08;忽略整数前的正负号&#xff09;。例如&#xff0c;输入-123&#xff0c;则忽略负号&#xff0c;由其百位1、十位2、个位3&#xff0c;然后计算3*1002*101 321&#xff0c;并输出321。 输入格式要…

迁移率随载流子浓度变化

载流子迁移率随载流子浓度变化&#xff0c;弱场下几乎保持恒定&#xff0c;然而随着载流子浓度变大&#xff0c;迁移率开始下降 从上面的公式可以得出&#xff0c;在浓度很小的时候&#xff0c;迁移率保持在最大值&#xff0c;当浓度比参考浓度大很多的时候&#xff0c;迁移率…

半导体器件物理 2022.10.13

漂移电流由两部分组成 扩散电流 扩散电流漂移电流就是总的电流&#xff0c;在实际问题中漂移电流远远大于扩散电流 空间电荷限制电流&#xff0c;对于本征半导体和一些绝缘体里面的电流&#xff0c;我们的作业 我们首先忽略我们的扩散电流&#xff0c;只考虑扩散电流 电流密度…

半导体材料参数介绍-很有用

上期文章我们最后提到了半导体参数&#xff0c;之所以专门挑一篇文章来说&#xff0c;因为它确实比较重要&#xff0c;可以让我们明白当前各种半导体材料的优势与劣势的原因。 不仅如此&#xff0c;还可以让我们明白一些东西&#xff0c;特别是二极管和三极管的一些特性。 其实…

silvaco-mobility models(1)

1.前一阶段的问题 大概接触了一段时间的silvaco&#xff0c;根据《InP基PIN开关二极管结构设计与制备》这篇文章提供的结构和一些简单的参数进行仿真。因为已经工作&#xff0c;没有老师在自己摸索&#xff0c;学习期间看到很多人写的心得或理解&#xff0c;或多或少都对我有所…

研究蛋白和DNA的相互作用—EMSA(凝胶迁移或电泳迁移率实验),可用于DAP-seq后续验证

技术简介 凝胶迁移或电泳迁移率实验&#xff08;EMSA,Electrophoretic Mobility Shift Assay&#xff09;是研究DNA结合蛋白和其相关的DNA结合序列相互作用的技术&#xff0c;可用于定性和定量分析。可用于DAP-seq后续验证实验。 EMSA实验&#xff0c;基于生物素标记探针与对应…

网络迁移学习率调整思路

在将HRNet从PyTorch框架向MindSpore迁移的过程中&#xff0c;由于初始学习率的选择不好&#xff0c;导致了最终精度没有达到预期要求。 文末有总结。 具体实验过程如下&#xff1a; 实验过程 优化器&#xff1a;SGD 初始学习率&#xff1a;0.01 学习率调整策略&#xff1a;p…

【迁移攻击笔记】数据集の变化→提高迁移率!Improving Transferability of Adversarial Examples with Input Diversity

1.作案动机 已知&#xff1a; 迭代攻击&#xff08;eg.I-FGSM&#xff09;过拟合且易陷入局部最优&#xff0c;不适合迁移。 单步攻击&#xff08;eg.FGSM&#xff09;欠拟合&#xff0c;不适合迁移。 对输入进行图像处理可以有效抵抗对抗攻击。 推测&#xff1a; 图像处理之后…

为什么NMOS管比PMOS管用得多--电子迁移率-宽禁带-半导体材料参数介绍

上期文章我们最后提到了半导体参数&#xff0c;之所以专门挑一篇文章来说&#xff0c;因为它确实比较重要&#xff0c;可以让我们明白当前各种半导体材料的优势与劣势的原因。 不仅如此&#xff0c;还可以让我们明白一些东西&#xff0c;特别是二极管和三极管的一些特性。 其实…

silvaco 第三章迁移率模型

记录模型都是什么 都用了什么 低场迁移率&#xff1a; 1 MUN and MUP parameters to set constant values for electron and hole mobilities and optionally specify temperature dependence. 2 using a look-up table model (CONMOB) to relate the low-field mobility at…

基于形变势理论计算载流子迁移率

载流子迁移率通常指半导体内部电子和空穴整体的运动快慢情况&#xff0c;是衡量半导体器件性能的重要物理量&#xff0c;例如对石墨烯、黑磷等二维材料展现出的高载流子迁移率的研究。由于电子在运动过程中不仅受到外电场力的作用&#xff0c;还会不断的与晶格、杂质、缺陷等发…

Silvaco 学习笔记 3——物理模型:迁移率模型

迁移率模型一般可以分为一下四种&#xff1a; 1.低场行为&#xff1a;此时载流子与晶格几乎处于平衡&#xff0c;其迁移率具有典型的低场值&#xff0c;一般用来表示。 低场载流子的迁移率可以采用5种不同的方式进行定义&#xff1b; 第一种方法使用MUN和MUP参数设置电子和空穴…

手把手地实操迁移率计算|附代码

迁移率可以用来分析资产变化情况&#xff0c;能够形象的展示客户贷款账户在整个生命周期的变化轨迹&#xff0c;也是预测未来坏账损失的常用指标。 迁移率计算步骤&#xff1a;&#xff08;以M0-M1为例&#xff09; 1、在月末或者&#xff08;账单结算完成日&#xff09;&#…

迁移率 计算方法及用途 风控建模系列 02

迁移率 计算方法及用途 风控建模系列 02 在上一篇博客中&#xff0c;我们讲解了vintage分析的原理及方法&#xff08;https://blog.csdn.net/weixin_44239904/article/details/99745084&#xff09;。而迁移率经常与vintage分析一同被人提到&#xff0c;不少人对这两者傻傻分不…

go 类型断言

switch 语句 switch k {case 0:println("fallthrough")fallthrough/*Go的switch非常灵活&#xff0c;表达式不必是常量或整数&#xff0c;执行的过程从上至下&#xff0c;直到找到匹配项&#xff1b;而如果switch没有表达式&#xff0c;它会匹配true。Go里面switch默…

java断言是什么_Java断言

断言的概念 断言用于证明和测试程序的假设&#xff0c;比如“这里的值大于 5”。 断言可以在运行时从代码中完全删除&#xff0c;所以对代码的运行速度没有影响。 断言的使用 断言有两种方法&#xff1a;一种是 assert<> &#xff1b; 另一种是 assert<> &#xff…

C++ 断言

文章目录 前言assertstatic_assert 前言 断言(Assertion)是一种常用的编程手段&#xff0c;用于排除程序中不应该出现的逻辑错误。它是一种很好的Debug工具。其作用是判断表达式是否为真。C提供了assert和static_assert来进行断言。在C库中也有断言&#xff0c;其中断言与C的相…

SVA断言

目录 Assertion介绍什么是assertion&#xff1f;断言覆盖率断言语言的发展与进步类型划分立即断言并行断言并行断言的执行阶段assertion&#xff0c;property&#xff0c;sequencesequences sequence定义基本操作符号and操作符号intersect操作符号or操作符号first_match操作符号…

常见结构化存储系统架构

什么是结构化存储系统 结构化数据一般指存储在数据库中&#xff0c;具有一定逻辑结构和物理结构的数据&#xff0c;最为常见的是存储在关系数据库中的数据&#xff1b;非结构化数据&#xff1a;一般指结构化数据以外的数据&#xff0c;这些数据不存储在数据库中&#xff0c;而…

DRAM存储系统结构

这几天在学习DRAM存储结构的基本知识&#xff0c;为了更好地理解DRAM结构的基本知识&#xff0c;仔细阅读了Memory Systems Cache, DRAM, Disk这本书中第十章节的内容&#xff0c;并翻译了所述内容。为了方便以后查阅&#xff0c;把所做笔记记录一下。 DRAM存储系统结构 前几章…