当前位置: 首页 > news >正文

逆序对——归并排序

逆序对:满足a[i]>a[j]i<j这两个条件

25级校队训练赛502 - Virtual Judgehttps://vjudge.net/contest/808881#problem/D

题目描述:现有n个数组成了一个序列,求这段正整数序列中逆序对的数目并输出

解题思路:采用归并排序的方法进行计算

代码展现:

第一种:

#include <bits/stdc++.h>
using namespace std;
int n,a[500010],c[500010];
long long ans;
void msort(int b,int e)//b为左边界,e为右边界
{
if(b==e)
return;//当左右边界相等的时候,递归结束
int mid=(b+e)/2,i=b,j=mid+1,k=b;
//mid将数据分成了左半部分和右半部分;
//i和j此时为左右两部分开始的值,k是临时数组c的索引下标,
//k专门标记要把元素写到临时数组c的那一个位置 ,用于合并两个有序子数组

msort(b,mid),msort(mid+1,e);//保证左右区间都是严格升序的有序数组
while(i<=mid&&j<=e)//i不能超过左半部分的最右边,j不能超过右边界
{
if(a[i]<=a[j])
c[k++]=a[i++];
//左元素小于右元素:
//把a[i]写到临时数组的k位置

else{
c[k++]=a[j++];
//左元素大于右元素,此时满足a[i]>a[j]&&i<j这个条件
//把a[j]写到临时数组的k位置

ans+=mid-i+1;
//逆序对数量=左区间剩余未遍历的元素个数=mid-i+1
}
}
while(i<=mid)
c[k++]=a[i++];//合并循环结束后,把元素写入c数组中,不产生多余的逆序对
while(j<=e)
c[k++]=a[j++];//合并循环结束后,把元素写入c数组中,不产生多余的逆序对
for(int l=b;l<=e;l++)
a[l]=c[l];//把存入临时数组c中的数据拷贝回a数组中,更新值
}

int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
msort(1,n);
cout<<ans;
return 0;
}

第二种:

#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
int a[N], tmp[N];
long long ans = 0;
void merge(int l, int r){
if(l >= r) return;
int mid = (l + r) /2;
merge(l, mid);
merge(mid + 1, r);
int i = l, j = mid + 1, k = l;
while(i <= mid && j <= r)
{
if(a[i] <= a[j]){
tmp[k++] = a[i++]; }
else
{ tmp[k++] = a[j++];
ans += mid - i + 1; }
}
while(i <= mid)
tmp[k++] = a[i++];
while(j <= r)
tmp[k++] = a[j++];
for(int p = l; p <= r; p++)
a[p] = tmp[p];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
for(int i = 1; i <= n; i++)
{
cin >> a[i];
}
merge(1, n);
cout << ans << endl;
return 0;
}

两种代码中的核心算法始终为:

void msort(int b,int e)//b为左边界,e为右边界
{
if(b==e)
return;//当左右边界相等的时候,递归结束
int mid=(b+e)/2,i=b,j=mid+1,k=b;
//mid将数据分成了左半部分和右半部分;
//i和j此时为左右两部分开始的值,k是临时数组c的索引下标,
//k专门标记要把元素写到临时数组c的那一个位置 ,用于合并两个有序子数组
msort(b,mid),msort(mid+1,e);//保证左右区间都是严格升序的有序数组
while(i<=mid&&j<=e)//i不能超过左半部分的最右边,j不能超过右边界
{
if(a[i]<=a[j])
c[k++]=a[i++];
//左元素小于右元素:
//把a[i]写到临时数组的k位置
else{
c[k++]=a[j++];
//左元素大于右元素,此时满足a[i]>a[j]&&i<j这个条件
//把a[j]写到临时数组的k位置
ans+=mid-i+1;
//逆序对数量=左区间剩余未遍历的元素个数=mid-i+1
}
}
while(i<=mid)
c[k++]=a[i++];//合并循环结束后,把元素写入c数组中,不产生多余的逆序对
while(j<=e)
c[k++]=a[j++];//合并循环结束后,把元素写入c数组中,不产生多余的逆序对
for(int l=b;l<=e;l++)
a[l]=c[l];//把存入临时数组c中的数据拷贝回a数组中,更新值
}

http://www.jsqmd.com/news/897136/

相关文章:

  • 源代码论文分享|绿城郑州爱心公益网站!
  • 清华大学thuthesis LaTeX模板:在Overleaf上快速完成学位论文的终极指南
  • CSS 布局与可视化高频:居中、BFC、Flex 与 Grid
  • 2026.5.27中山黄金回收商家榜单出炉 正规机构实测优选指南 - 资讯纵览
  • Vidupe:如何利用智能视频指纹技术快速清理重复视频文件
  • MagiskOnWSALocal 终极指南:3步让Windows安卓子系统拥有完整Root权限
  • 终极指南:如何高效打包Windows全平台虚拟化驱动
  • AI智能体产业学院是什么?
  • ResNet深度剖析:残差连接如何破解深度网络训练难题?
  • 思特威携手紫光展锐联合布局MicroLED高速光互连,筑牢国产AI算力底座
  • 从引脚到性能:DVP与MIPI接口的实战选型指南
  • 低成本自制星链无线路由器,灵活配置还能多样升级!
  • ESMFold终极实战指南:5个高效预测蛋白质3D结构的专业方案
  • 国内高校学生必备的AI写作辅助网站有哪些?
  • Aurora Store:构建无Google依赖的Android应用生态解决方案
  • 国家中小学智慧教育平台电子课本解析工具:解锁教材下载新体验
  • 脉冲神经网络:从生物启发的计算模型到高效能AI的未来
  • 微积分的逻辑基石:从无穷小到极限的严密化之路
  • 化工危化场所抗爆墙选型合规厂家全场景问答 - 奔跑123
  • Pearcleaner:重新定义macOS清理体验的开源工具
  • 如何用BG3脚本扩展器彻底改变你的博德之门3游戏体验?
  • 让桌面“活“起来:DyberPet桌面宠物框架,打造属于你的专属数字伙伴
  • 如何通过图像识别技术实现鸣潮游戏自动化:完整指南与架构解析
  • 基于Flutter与Arduino的乌尔都语盲文学习系统设计与实现
  • ESMFold终极指南:5种高效蛋白质结构预测解决方案深度解析
  • 【ChatGPT播客冷启动生死线】:前7期内容策划SOP(含话题热度预测模型+听众情绪图谱工具链)
  • DRAM地址映射优化:破解高速光通信交织器行列访问瓶颈
  • 「研究分析·适配解析·优化方案·避坑指南·体系总结」基层工作宣传稿发稿渠道内容审核、合规风控、媒体适配与收录优化、长效留存全维度实操指引
  • 5分钟上手:浏览器多URL批量打开工具Open-Multiple-URLs
  • SRWE完整教程:免费Windows窗口编辑器终极指南,轻松调整任意程序窗口