树状数组求逆序对

逆序对之树状数组 [树状数组]逆序对题目题目解析算法简介树状数组代码实现 题目 题目解析 逆序对可以用归并排序和树状数组: 归并排序就不用讲了,我们来讲讲树状数组 算法简介 树状数组 树状数组(Binary Indexed Tree(B.I.T), Fenwick Tree)是一个查询和修改复杂度都为log⁡2n\log_2{n}log2​n的数据结构。主要用于查询任意两位之间的所有元素之和,但是每次只能修改一个元素的值;经过简单修改可以在log⁡2n\log_2{n}log2​n的复杂度下进行范围修改。 这种数据结构 阅读详情

一般来说,求逆序对,方法如下:
1、如果 N<10000,可以用冒泡排序,交换次数就是逆序对数量,时间复杂度 O(n2),空间复杂度 O(n)
2、如果 N>=10000,用归并排序,是分治思想,时间复杂度 O(nlog2n),空间复杂度 O(2*n),见上面参考代码。
3、如果 K 表示最大元素和最小元素的差值,当 N 大于400000,K=50000 的时候,树状数组比分治更快,时间复杂度 O(nlog2K),空间复杂度 O(K)。

树状数组求逆序对的方法,在考场上不失一个好的选择,因为它不仅速度更快,而且代码也比较简单,因为我们是以数的大小为下标,所以情况可以分为两种,
第一种为题目给的需要求逆序对的数列的最大值太大,如果直接作为下标会浪费大量的空间,这时候需要离散化点值,使它缩小到我们可控的范围之内;
第二种则是数列大小恰好在N的范围内,即a[]max<=N,可以直接计算;

我们巧妙地运用了巧妙的树状数组,其中树状数组里面的a[](原数组)的下标表示的就是A序列里面的元素。例如:当A={3,3,1,9,11},循环时依次在a[3],a[3],a[1],a[9],a[11]加一。聪明的读者应该知道这个方法怎样实现了。没错,就是先读入元素ai,再将a[i]加一,然后用树状数组的特点在O(log2K)的时间复杂度求出Σa[k](1<=k<=i)。这样对于之前读入而且小于等于ai的元素个数为Σa[k],读入的ai为第i个元素,所以在ai前面且比ai大的元素为i-Σa[k],问题得以解决。

我们来看一道例题:

Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平衡是个梦想。因为有很多奇异的物种拥有各种不稳定的能量,平衡瞬间即被打破。KB决定求助于你,帮助他完成这个梦想。 一串数列即表示一个世界的状态。
平衡是指这串数列以升序排列,而从一串无序数列到有序数列需要通过交换数列中的元素来实现。KB的能量只能交换相邻两个数字。他想知道他最少需要交换几次就能使数列有序。
输入格式
第一行为数列中数的个数 N(n≤100000)。
第二行为 N 个数 a1~an (每个数小于100000),表示当前数列的状态。
输出格式
输出一个整数,表示最少需要交换几次能达到平衡状态。
这道题的题意就是求数列a中的逆序对的个数,我们注意到,“a1~an (每个数小于100000)”,所以这道题也就不需要离散化,可以直接求

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<cstring>
#include<string>
#include<cctype>
#include<set>
#include<queue>
using namespace std;
long long  n,x,tree[100005],ans; //不用long long 会在最后一个点溢出 
//---------------------
inline int lowbite(int i)
{
    return i & (-i);
}
//---------------------
inline void Update(int i,long long t)
{
    while(i<=n)//体会一下为什么我们用a[]做下标,却是i<=N
    {
       tree[i]+=t;
       i+=lowbite(i);
    }
}
//---------------------
inline int query(long long i)
{
    long long  tmp=0;
    while(i>0)
    {
        tmp+=tree[i];
        i-=lowbite(i);
    }
    return tmp;
}
//---------------------
int main()
{
    freopen("dream.in","r",stdin);

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        Update(x,1);
        ans+=(i-query(x));
    }
    cout<<ans;
    return 0;
}

代码中的问题就是因为“a1~an (每个数小于100000)”,所以就可以直接i<=n,否则就需要离散化。

POJ2299就是需要离散化得情况,离散化得过程如下:

 离散化是一种常用的技巧,有时数据范围太大,可以用来放缩到我们能处理的范围,必要的是建立一个结构体a[n],v表示输入的值,order表示原i值,再用一个数组aa[n]存储离散化后的值  
 例如: 
 i:1 2 3 4 5 
 v: 9 0 1 5 4 
 排序后:0 1 4 5 9 
 order:2 3 5 4 1 如果建立映射:aa[a[i].order]=i; 
 aa:5 1 2 4 3 
 即原本的9经过排序应该在第5位,现在aa[1]=5,对应原来的9,大小次序不变,只是将9缩小到了5

其余过程大体同上,在此就不赘述。

树状数组——求逆序对个数(初学者都能看懂) 在网上翻看了一些博客,感觉大体对于树状数组求逆序对的讲解不够详细,那些博客,更多像是给已经学会逆序对的人复习用的。而初学者,可能要冥思苦想。接下来,我便从一个初学者的角度,来一步步的,讲解一下由树状数组求逆序对。需要的前置知识只有,会线段数组的基本应用。单点更新,区间查询,求lowbit。 先贴树状数组的基本代码。 求lowbit int lowbit(x){return x&(-x);} 单点更新 void update(int x,int y,int n){ for(int i=x;i 阅读详情

相关推荐

Python爬虫实战:5分钟搞定大众点评评论数据抓取(附完整代码)

本文详细介绍了使用Python爬虫高效获取大众点评评论数据的5个关键技巧,包括环境配置、智能页面解析、反反爬策略、数据存储与容错设计以及性能优化。通过实战案例和完整代码,帮助开发者快速掌握文本挖掘技术,适用于市场分析和商业决策。

weixin_30660027的博客 290

树状数组之求逆序对

树状数组之求逆序对 逆序对    设 A 为一个有 n 个数字的有序集 (n>1), 其中所有数字各不相同。 如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A [i] > A [j], 则 <A [i], A [j]> 这个有序对称为 A 的一个逆 序对,也称作逆序数。 例如,数组 (3,1,4,5,2) 的逆序对有 (3,1),(3,2),(4,2),(5,2), 共 4 个。 原理 我们有以下的设定 a[]={0,3,1,4,5,2} 其中 3,1,

DC_Fan的博客 2463

开源DIY龙门架:从零构建可编程运动控制平台

运动控制是自动化与机器人技术的核心基础,它通过精确指令驱动执行机构,实现物体的定位与轨迹规划。其原理通常涉及控制器、驱动器、电机与传动机构的协同工作,核心价值在于将数字指令转化为精准的物理运动,从而解放人力并提升作业一致性。在工业自动化、桌面制造(如3D打印、激光雕刻)及教育机器人等领域应用广泛。本文聚焦于一个具体的工程实践案例:使用**铝型材**、**3D打印**零件、Arduino控制器及步进电机,从机械结构设计、电路连接到代码编写,手把手教你打造一个模块化、可扩展的开源龙门架系统。该系统不仅成本可控,

weixin_33168937的博客 614

树状数组(求逆序对)

一、树状数组是什么 树状数组,又称二进制索引树,英文名Binary Indexed Tree 之前遇到一个求逆序对的题,看了很多题解都只说了这个树状数组,关于怎么实现的全都避而不谈,我研究了一下午,总算搞出个头绪了 一般用来求前缀和,可以把时间复杂度从O(n)降到O(log10 n)非常恐怖,举个例子,假如我们要求从1~1000的前缀和,普通方法需要遍历1000次,而树状数组只需要遍历5次,...

卑鄙的我 2万+

大模型长对话中上下文无法承载全部历史,如何压缩或提取重点

如果说截断和滑动窗口是“硬性”压缩,那摘要生成技术就显得“软”多了,也更接近于智能化的解决方案。它的思路是:不直接丢弃历史,而是通过自然语言处理(NLP)技术,把冗长的对话记录浓缩成一段简短的摘要,保留核心信息。这样既能大幅减少token数量,又不至于丢失关键内容。这种方法通常会借助预训练模型,比如BART或T5,它们擅长从长文本中提取重点内容。

大模型大数据攻城狮的专栏 1584

8,9,10,11,12,13代CPU特制win7 64位系统

对于7代以上的CPU装win7,在UEFI的模式下,如果不提前注入显卡驱动,就会一直卡在LOGO界面。对于此情况,我们推出一个内置了显卡和USB驱动的特制版win7系统。由于单文件已经大于了4G,所以推荐使用rufus来写入镜像安装。如还有问题,请记录下电脑配置,联系QQ11717907。制作完成以后,就可以通过U盘启动安装了。

海康威视技术支持 7249

树状数组简单总结(原理见以往帖子)

树状数组:快速(动态)求前缀和 在线算法(支持修改) O(logn) 1:给某个位置上的数加上一个增量(修改某个元素) 2:求某个前缀和 即:单点修改,区间查询(sum(r)-sum(l-1)) 树状数组只能支持这俩问题,别的问题都得通过转化才能解决 比如区间修改,单点查询 需要利用差分转化为区间修改 记树状数组为C[x],定义: C[x]=(x-lowbit[x],x],即x-lowbit[x]+1~x,奇数为其本身 lowbit[x]=x&-x,含义是2^k,k为x...

明月千里赴迢遥的博客 681

基于深度学习的人脸识别考勤管理系统,采用YOLOv11和Dlib算法实现人脸识别和考勤签到,前台人脸识别和签到系统 + 后台人脸和考勤管理系统,全网独发

基于深度学习的口罩人脸识别的考勤管理系统,采用YOLOv11和Dlib算法实现人脸识别和考勤签到,前台人脸识别和签到系统 + 后台人脸和考勤管理系统,全网独发

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 1824

超详细笔记:树状数组求解逆序对数

纯纯蒟蒻看不懂各位大佬的题解,搜集了各路大佬的思考方式,做出一些小总结,关于整个思考过程,怎么想到离散化,怎么想到树状数组的过程,而不只是给出解法,大佬轻喷,文章仅供和我一样不太理解的萌新们找找感觉,因为详细所以十分啰嗦,才能保证看得懂,请见谅。题目原意:对于给定的一段正整数序列,逆序对就是序列中 ai​>aj​ 且 i<j 的有序对,求长度为n的序列的逆序对数总数。(n在50W以内,时间复杂度必须在 nlogn 内)这里不做线段树解法和归并排序的解法(大佬们都讲的很清楚了)仅考虑树状数组。

Island_0801的博客 4310

第2章-系统控制原理 -> 经典控制理论

第1章 回到目录 第3章 2 控制原理2.1 控制系统的数学模型2.1.1 时域数学模型2.1.2 复域数学模型2.2 线性系统的稳定性2.2.1 复数域稳定判据2.2.2 频率域稳定判据2.3 线性系统状态空间模型2.3.1 状态空间表达式2.3.2 状态空间系统设计2.4 李雅普诺夫稳定性分析2.4.1 李雅普诺夫稳定性2.4.2 李雅普诺夫稳定判据 2.1 控制系统的数学模型 2.1.1 时域数学模型 2.1.2 复域数学模型 2.2 线性系统的稳定性 2.2.1 复数域稳定判据 2.2....

赵继超的笔记 5549

32、社交媒体大数据中的情感分析与网络欺凌检测

本文探讨了社交媒体大数据在情感分析和网络欺凌检测中的应用。情感分析有助于应对自动化带来的社会变化、促进社会包容和推动环境保护。网络欺凌作为一种严重的在线危害,其检测依赖于数据预处理、特征提取与深度学习模型(如CNN、LSTM)进行分类。文章还总结了大数据在欺诈检测、医疗、制造、交通等领域的广泛应用,并分析了数据存储、处理速度、质量和技术工具等方面的挑战,提出了相应的应对策略。未来,随着技术进步,社交媒体大数据将在更多领域发挥关键作用。

cc789的博客 90

树状数组+求逆序对

右图圆圈中标记有数字的结点,存储的是称为树状数组的tree[]tree[]。一个结点上的tree[]tree[]的值,就是它树下的直连的子结点的和。例如: tree[1]=a1​ tree[2]=tree[1]+a2​ tree[3]=a3​ tree[4]=tree[2]+tree[3]+a4​ ⋯ tree[8]=tree[4]+tree[6]+tree[7]+a8​ 而我们利用tree[],有效地完成下面两个操作: 查询,即求前缀和sum,例如: sum(8)=tre...

weixin_62355410的博客 2762

SAP 创建PO时提示“不能确定任何组件”

SAP 创建委外加工的PO时提示“不能确定任何组件” 而如果BOM已经创建了,但还是提示该错误保存。 解决办法:1. BOM selection 未配置好; 2. 由于Purchasing prosessing time的设置,如果PO中的delivery time - Purchasing prosessing time是过去的日期,那么会找不到BOM,BOM的有效期需早 于PO审批的有效期。 3. BOM未...

willieyuan的博客 6115

【树状数组 求逆序对】排序

首先需要了解逆序对是什么:逆序对就是如果i &gt; j &amp;&amp; a[i] &lt; a[j],这两个就算一对逆序对。其实也就是对于每个数而言,找找排在其前面有多少个比自己大的数。那么思路就来了,树状数组又一次地优化了这种“需要遍历”的情况。那不就很容易了吗?依次把序列里的数放到树状数组中的A[i]上去(实际是以C[i]形式的插入函数),注意A[i]是以数值大小从小到大排列的。先插入...

It's the Climb 1万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

树状数组离散化求逆序对(模板)

考虑根据值来建树状数组 , 初始树状数组为全0。现在按照序列从左到右将数据的值对应的位置的数加一,代表又有一个数出现。因此,在循环到第项时,前项已经加入到树状数组内了 , 树状数组内比大的都会与构成逆序对,因为它们一定出现的更早,所以产生的逆序对数量为(表示当前比小的个数,为总的个数,相减就是前面,比大的个数了,也就是当前数的逆序对)。当然也可以直接用来求。 #...

sugarbliss 683

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

洛谷 P4378 —— 树状数组求逆序对

除了朴素求逆序对,常见的求逆序对主要有两种方法。

Miserable_ccf的博客 849

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

利用树状数组求逆序对

逆序对: ai>aj 且 i<j 。说白了就是一个序列中前面比后面大的对,举个例子: 序列2 1 4 3 2 , (2 1)就是一个逆序对,(4 3)、(4 2)也是。 暴力做法: 遍历这个序列,数一下每个元素前面比他大的元素的个数,累加就是最后的结果,举个例子: 序列2 1 4 3 2 第一个元素 2,前面没有元素,结果 = 0 第二个元素 1,前面比他大的是 2,结果 = 1 第三个元素 4,前面没有比他大的,结果 = 0 第四个元素 3,前面比他大的是 4,结果 = 1 第五个元素 2

weixin_45743427的博客 352

Tido 习题-二叉树-树状数组求逆序对

这里给大家提供一个全新的求逆序对的方法 是通过树状数组来实现的 题目描述 样例输入Copy 5 2 3 1 5 4 样例输出 Copy 3 提示 #include<iostream> #include<cstdio> #include<...

weixin_34410662的博客 425

树状数组求逆序对 poj2299

树状数组求逆序对; 对于一组任意顺序的数,记下他们的初位置,再进行排序,记下他们本来应该在的位置。然后,按最初位置从前往后,进行处理。 基本思想: 对于一个数要求它对应得逆序对,可以通过求前面小于等于它的数的个数,然后用当前已处理的数的个数-前面小于等于当前的数的个数得到。 如: 4 3 5 2 1 排序后 1 2 3 4 5 对于第一个数4,当前处理数的个数为1,本来应该在的位置是4,则在第4个...

weixin_43184669的博客 206

[树状数组]求逆序对

树状数组基本讲解: 树状数组的用途就是求前缀和,他的本质跟线段树相似,就是一个空间换时间。 主要采用lowbit,通过二进制从而划分区间。 增加的时候,从下往上依次加lowbit 查询的时候,从上往下减去lowbit。 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdl...

weixin_30561177的博客 111
上一篇: 2017.4.22NOIP2017模拟考试总结
下一篇: 一些解题过程中关于数据范围的细节
Amessal
博客等级 码龄10年 9粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值