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

洛谷 P1908:逆序对 ← 树状数组 + 离散化(数组 + sort + STL map)

【题目来源】
https://www.luogu.com.cn/problem/P1908

【题目描述】
猫猫 TOM 和小老鼠 JERRY 最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计。
最近,TOM 老猫查阅到一个人类称之为“逆序对”的东西,这东西是这样定义的:对于给定的一段正整数序列,逆序对就是序列中 ai>aj 且 i<j 的有序对。知道这概念后,他们就比赛谁先算出给定的一段正整数序列中逆序对的数目。注意序列中可能有重复数字。

【输入格式】
第一行,一个数 n,表示序列中有 n 个数。
第二行 n 个数,表示给定的序列。序列中每个数字不超过 10^9。

【输出格式】
输出序列中逆序对的数目。

【输入样例】
6
5 4 2 6 3 1

【输出样例】
11

【说明/提示】
对于 25% 的数据,n≤2500。
对于 50% 的数据,n≤4×10^4。
对于所有数据,n≤5×10^5。
请使用较快的输入输出。

【算法分析】
● 本题数据个数上限为 5e5,但数据范围至 1e9,比较稀疏,故需进行离散化。

● 传统的逆序对统计需要两两比较数值大小,需要检查 C(n,2)=n(n-1)/2 对组合,时间复杂度为 O(n²)。而“树状数组+离散化”方法,不直接比较“数值”,而是通过树状数组去查询“位置”的统计信息。通过巧妙的数据结构转换,将问题降维为高效的前缀和查询,时间复杂度为 O(logn) 。

● 逆序对问题可以用“树状数组+离散化”实现,其核心原理是‌“通过离散化建立数值到位置的映射,再利用树状数组高效维护和查询这些位置上的计数信息,从而避免了直接的数值两两比较”。
(1)树状数组的作用‌:树状数组的每个位置代表离散化后的一个值(一个“桶”),记录每个数值出现的次数。通过查询前缀和,可以快速知道小于等于某个值的数有多少个。
(2)离散化的必要性‌:原始数据的数值范围很大,但实际不同的数值个数有限。离散化将大范围的数值映射到连续的整数下标,减少空间占用。

● 树状数组的概念、结构及实现:https://blog.csdn.net/hnjzsyjyj/article/details/149672973

● STL map 简介​:https://blog.csdn.net/hnjzsyjyj/article/details/146118701

【算法代码】

#include <bits/stdc++.h>
using namespace std;typedef long long LL;
const int maxn=1e6+5;
int a[maxn],c[maxn],t[maxn];
map<int,int> mp;
int n,cnt=1;int lowbit(int i) {return (-i)&i;
}void pointUpdate(int i,int val) {while(i<=n) {c[i]+=val;i+=lowbit(i);}
}LL preSum(int i) {LL s=0;while(i>0) {s+=c[i];i-=lowbit(i);}return s;
}int main() {cin>>n;for(int i=1; i<=n; i++) {cin>>a[i];t[i]=a[i];}sort(t+1,t+n+1);for(int i=1; i<=n; i++) { //discretizationif(mp.find(t[i])==mp.end()) {mp[t[i]]=cnt++;}}LL ans=0;for(int i=n; i>=1; i--) {ans+=preSum(mp[a[i]]-1);pointUpdate(mp[a[i]],1);}cout<<ans<<endl;return 0;
}/*
in:
6
5 4 2 6 3 1out:
11
*/





【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/153254031
https://blog.csdn.net/hnjzsyjyj/article/details/146118701




 

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

相关文章:

  • P10977 Cut the Sequence 分析
  • 人工智能之数据分析 numpy:第十五章 项目实践
  • 租房买房必看1为什么户型不方正,会让你越住越穷?
  • 点灯笔记:PY32F002B
  • 软件工程学习日志2025.11.25
  • 实用指南:Stable Diffusion 短视频制作算力需求与优化策略研究
  • IT外包与勒索软件:英国经济安全面临的技术风险
  • NumPy广播机制深度解析:为什么有时能加,有时报错?
  • 2025年微信公众号编辑器Top7权威评测:全能型工具让效率提升300%
  • 如何高效地学习Java编程?
  • STL常用功能
  • 2025/11/25-Xs new location transparency feature unleashes questions about origins of MAGA accounts
  • 实用指南:【底层机制】深入浅出地、系统地剖析 Appium 的原理
  • Go 语言未来会取代 Java 吗?
  • 玄机钓鱼邮件分析_2025/11/25
  • 容错量子电路大幅降低资源开销
  • 详细介绍:【C基本功】类型转换的奇幻漂流
  • 点灯笔记:CW32L010
  • Rust 零拷贝技术:从所有权到专业的系统调用的性能优化之道
  • 服务器代码执行三板斧
  • 过山车
  • 2025年下半年奖牌/水晶奖杯/奖杯定制/定制厂家口碑推荐榜
  • day07 spark sql - 详解
  • 深入解析:系统架构设计师备考第57天——云原生架构相关技术
  • 2025年舒适操控的轮胎推荐:TOP5专业测评深度揭秘
  • 2025年宝马5系更换轮胎推荐:TOP5专业榜单权威推荐
  • 低代码 vs 无代码:核心差异、适用场景与选型决策
  • 【ArcMap】将一个线图层的属性字段连接到另一个线图层
  • 低代码平台选型指南:企业避坑指南与核心评估维度
  • detectron2 框架安装