【题解】逆序对(树状数组)

【题解】poj2299 树状数组求逆序对+离散化 题目链接 //采用树状数组求逆序对 离散化 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int N=5e5+10; struct node { int p,v; }q[N]; int ... 阅读详情

题面

【题目描述】
给定一个序列a1,a2,...,ana_1,a_2,...,a_na1​,a2​,...,an​,如果存在i<ji < ji<j并且ai>aja_i>a_jai​>aj​,那么我们称之为逆序对,求逆序对的数目。
【输入】
第一行为nnn,表示序列长度,接下来的nnn行,第n+1n+1n+1行表示序列中的第iii个数。
【输出】
所有逆序对总数。
【样例输入】

4
3
2
3
2

【样例输出】

3

【数据范围】
n<=105,ai<=105。n<=10^5,a_i<=10^5。n<=105,ai​<=105。

算法分析

归并对可以使用归并排序求解,在这里我们使用树状数组来实现。
(1)定义数组sss,s[x]s[x]s[x]表示数值为xxx出现的次数,即桶计数。
再定义树状数组ccc,c[x]c[x]c[x]表示数值在区间[x−lobit(x)+1,x][x-lobit(x)+1,x][x−lobit(x)+1,x]的个数。
(2)逆序访问nnn个数(a[n],a[n−1],...a[1]a[n],a[n-1] ,...a[1]a[n],a[n−1],...a[1]),对于a[i]a[i]a[i],统计前缀和sum(i−1)sum(i-1)sum(i−1),表示值范围在111 ~ i−1i-1i−1的个数,因为逆序访问,前缀和包含的数全部比a[i]a[i]a[i]小,且在a[i]a[i]a[i]后面,形成了逆序对sum[i−1]sum[i-1]sum[i−1]个。
(3)将每次前缀和相加,就是最后的答案。
(4)访问完a[i],就执行单点增加,数值为a[i]的个数+1,即s[a[i]]+1。
如果数值太大,桶装不下怎么办呢?可以使用离散化,所谓离散化就是把无限空间中有限的个体映射到有限的空间中去,以此提高算法的时空效率。通俗的说,离散化是在不改变数据相对大小的条件下,对数据进行相应的缩小。
例如:我需要求解序列:99999999 199999999 88888888的逆序对,实际可以看作是求序列:1 3 2的逆序对,因为逆序对跟大小关系有关,和具体的值无关。
【程序实现】:
这里的s数组,可以不使用,方便大家理解。

#include<bits/stdc++.h>
#define N 500100
using namespace std;
int n,c[N],a[N],maxn;
int lowbit(int x)
{
    return x&(-x);
}
void update(int x,int val)
{
    for(int i=x;i<=maxn;i+=lowbit(i))	
        c[i]+=val;
}
int sum(int x)
{
    int ans=0;
   for(int i=x;i>0;i-=lowbit(i))
        ans+=c[i];
    return ans;
}
int main()
{
    scanf("%d",&n);
    long long ans=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        maxn=max(maxn,a[i]);	//最大值 
    }
    for(int i=n;i>=1;i--)
    {
        ans+=(long long)sum(a[i]-1);
        update(a[i],1);
    }
    cout<<ans<<endl;
    return 0;
 } 
银河麒麟系统V10 Server SP1 安装Oracle 19c •oracle-database-preinstall-19c 这个工具会自动配置系统参数,创建 oracle 用户和组。比较方便。•••••银河麒麟高级服务器操作系统V10 - 国产操作系统、银河麒麟、中标麒麟、开放麒麟、星光麒麟——麒麟软件官方网站。 阅读详情

相关推荐

基于Android13的系统启动流程分析(三)之FirstStageMain阶段

init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等。init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init1. Bootloader 引导当按下设备电源键时,最先运行的就是 bootloader(固化在ROM的程序),bootloader 的主要作用就是硬件设备(如 CPU、flash、内存)的初始化并加载到RAM,通过建立内存空间映射,为装载 Linux 内核做好准备,。

q1210249579的博客 5496

逆序对——树状数组

通过建立树状数组并结合离散化处理,可以高效地统计序列中每个元素与其之前的元素构成的逆序对数量。离散化确保了空间复杂度在可接受范围内,而排序时考虑元素出现顺序则避免了相等元素导致的错误。

qq_73702550的博客 1158

服务器被矿工入侵记录

一次服务器被矿工入驻的处理记录

王瑞的技术专栏 1333

树状数组(求逆序对)

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

卑鄙的我 2万+

别再为授权费头疼了!手把手教你免授权搞定西门子、马扎克等12种主流数控机床的数据采集

本文提供了一套免授权采集西门子、马扎克等12种主流数控机床数据的实战指南,帮助中小型机加工车间节省80%以上的采集成本。通过TCP/UDP协议逆向工程和跨平台数据整合,实现经济、灵活且可持续的数据采集方案,涵盖设备兼容性处理、数据频率优化等关键问题。

weixin_26873711的博客 709

从外包到转正:一个华为OD亲历者的真实工作体验与避坑指南

本文分享了一位华为OD员工从外包到转正的真实经历与实用建议。通过详细解析华为OD的日常工作、转正核心指标、机试备考技巧及职场突围策略,为读者提供了一份全面的避坑指南。特别针对机试E卷的高频考点和刷题方法,给出了具体的数据分析和实战经验。

weixin_33686714的博客 705

树状数组求逆序对

树状数组求逆序对先回顾树状数组区间查询区间查询&区间修改什么是逆序对,以及如何求求逆序对的方法如何用树状数组维护求逆序对逆序对题目 先回顾树状数组 树状数组是查询和修改都是logn的一种数据结构。 它里面的每个节点的值=自己加上所有子节点的值的和 有区间查询,单个节点的功能: 区间查询 求某段区间上所有数的和,是树状数组的强项。然鹅,他最常用的方法仅仅仅仅只是求前缀和 当然,也可以求区间和,让两个前缀相减即可 int lowbit(int x) { retrurn x&-x; } int

qq_45895217的博客 2053

C/C++面试八股文汇总

以对象管理资源,利用的就是C++构造的对象最终会被对象的析构函数销毁的原则。上述的的申请、使用、释放资源的程序较为简单,但是如果程序很复杂的时候,需要为所有的new 分配的内存delete掉,导致极度臃肿,效率下降,更可怕的是,程序的可理解性和可维护性明显降低了,当操作增多时,处理资源释放的代码就会越来越多,越来越乱。栈在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。

wzzrh的博客 1万+

逆序对之树形数组与归并排序

1.逆序对问题 逆序对,何为逆序对?逆序对就是在一序列array[]中,其中存在两个元素array[i]和array[j],满足下列关系:i=0 jarray[j],这一对数(array[i] , array[j])就是逆序对,要是给定一个任意的序列,那怎么求逆序对的数量呢? 求解该问题有两个经典的方案: 基于树状数组来求解在归并排序的基础上求解 下面我们将慢慢介绍这两种算法:

qeesung的专栏 5721

ppt保存时嵌入字体,但找不到字体使用的位置的解决办法

摘要 当PPT提示无法保存嵌入字体时,可通过VBA代码快速定位使用该字体的文本。具体步骤如下: 按ALT+F11打开VBA编辑器,新建模块并粘贴提供的代码; 运行代码后输入目标字体名称(如“方正兰亭黑简体”); 程序将列出所有使用该字体的幻灯片编号及对应文本内容; 修改这些文本的字体即可解决保存问题。该方法高效精准,适用于排查PPT字体嵌入失败的情况。(150字)

智慧空间实验室 1401

MediaPipe 教程:从安装到应用-全网最全

MediaPipe是Google推出的开源框架,专为构建机器学习管道设计,可以高效处理视频、音频等时间序列数据。本文教程从安装到应用逐步讲解: 安装步骤简单,只需通过pip安装mediapipe包并验证版本; 重点演示人体姿态检测功能,可识别33个身体关键点; 提供基础代码实现,包括视频捕获、关键点检测与可视化; 强调模块化开发,将功能封装成类以提高代码复用性。 教程适合初学者,通过清晰指引和实用代码示例,帮助快速实现计算机视觉应用。

FJN110的博客 1563

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

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

Island_0801的博客 4310

《网络安全自学教程》- 防火墙原理分析与Windows防火墙使用配置

防火墙分类及原理,Windows开启防火墙,Windows防火墙添加策略,

wangyuxiang946的博客 1万+

楼兰图腾 【题解】 树状数组 逆序对

题目链接:https://ac.nowcoder.com/acm/contest/1032/A (话说CH挂了,可以在牛客上面交) 因为x是按顺序的,那么就是求一个逆序对。 考虑树状数组求逆序对。 两个数组,lt[ ],rt[ ]。 lt[i]表示 a[i] 前面有几个数比它小。 rt[i]表示 a[i] 后面有几个数比它小,也就是逆序对。 那么" ^ "的数量就是所有 l...

dazhishu2366的博客 213

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

权值树状数组,逆序对思路及题解

逆序对思路及题解

Li_yue_zhen的博客 374

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

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

星星之火OIer:逆序对(树状数组)题解

逆序对题解出处(1266) 老实说,还没有归并排序快 先上代码,再解释 #include<cstdio> #include<algorithm> using namespace std; inline void read(long long &x) { x=0; long long f=1; char s=getchar(); ...

qq_43890190的博客 383

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

P1908 逆序对(这个为树状数组解法)

题解:本题主要考查树状数组求逆序对,先将数据按值的大小排序注意判重,再构建树状数组 代码如下: #include<iostream> #include<algorithm> using namespace std; struct node { int num,v; }a[7346278]; int tree[2342345]; long long n,sum=0; ...

wly1127的博客 264

线段树/树状数组 | 洛谷P1908 逆序对题解

本文总结了计算逆序对数量的两种高效方法:归并排序和树状数组/线段树。归并排序在排序过程中通过合并阶段统计逆序对,时间复杂度为O(nlogn)。树状数组和线段树则需先离散化数据,通过动态维护和查询区间统计逆序对。树状数组代码更简洁,但线段树适用性更广。文中提供了相关代码实现,并比较了两种数据结构的差异,强调处理离散化和重复元素的技巧。两种方法都能在合理复杂度内解决大规模逆序对问题。

2501_93040725的博客 514

洛谷 P1908 逆序对 题解 归并排序/树状数组/线段树

归并排序 树状数组 线段树 洛谷题解 C++代码 附注释

一只摸鱼的bbc 1394

题解:逆序对的计算

逆序对的计算是算法学习中的一个基础问题,有多种方法可以解决。暴力法虽然简单,但在数据量大时效率较低。归并排序法和树状数组法都是时间复杂度为 (O(n \log n)) 的高效方法,适用于处理大规模数据。选择合适的方法可以根据具体问题和数据量来决定。版权声明:本博客内容为原创,转载请保留原文链接及作者信息。参考文章算法篇:逆序对-优快云博客求逆序对数的三种方法 | 2005ZHW’s Blog。

ning的博客 1345

题解 SP4226 【MSE06H - Japan】(树状数组+逆序对)

传送门 题目描述 日本计划迎接ACM-ICPC世界总决赛,为此必须修建大量道路。日本是一个高岛,东海岸有N个城市,西海岸有M个城市(M <= 1000, N <= 1000)。将修建K条高速公路。每个海岸的城市编号分别是1、2、……从北到南。每条高速公路都是一条直线,连接着东海岸的城市和西海岸的城市。建设资金由ACM担保。其中很大一部分是由高速公路之间的交叉点数量...

weixin_30338497的博客 759

『莫队·树状数组』Mato的文件管理

题解 对于区间询问,我们可以想到莫队,而逆序对则需要用树状数组来维护。 因此我们便可以动态维护区间的逆序对。例如: 删除左边的点,要在删去树状数组中比它小的点。加如左边的点,则加入树状数组中比它小的点。 删除右边的点,就删除比它大的点,因为右边的点点往往处于逆序对中的较小者,而左边则属于较大者。 然后用莫队和树状数组维护即可。 代码如下: #include <bits/stdc++.h...

Ronaldo7_ZYB的博客 274

bzoj4240有趣的家庭菜园————贪心+逆序对+树状数组

题解:本题主要考查贪心+逆序对 简要题意:一个序列移成一个前一段单调不降,后一段单调不升的序列最少要交换多少次 。 1.贪心:先把序列从大到小排序,最大值放在中间,次高的在左边或右边谁逆序对少就在哪边。 2.逆序对:对于一个数列下标1…n,把它进行操作后得到的下标为241…那么交换次数即为这个新数列的逆序对数。 3树状数组:求逆序对 代码如下: #include<iostream> #...

wly1127的博客 216

洛谷p1966火柴排队题解

ps:鉴于你们的蒟蒻yxj实在太蒻辽, 所以, 看不懂也是正常的........ 树状数组 xxy学姐给我们讲的树状数组, 她讲的真的是太好啦!qwq!吹爆xxy 然后, 为了巩固自己, 硬着头皮写题解 题目链接 读完题之后来分析是要求逆序对 可以先离散化 因为我们要顺序存, f1数组的第i小和f2数组的第i小在同一个位置一定就是最优的 然后再求在离散化的那个数组里的逆序...

weixin_30586257的博客 177

[NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)

[NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二列火柴中第 i 个火柴的高度。 每列火柴中相邻两根火柴的位置都可以交...

aua4137的博客 261

P3157 动态逆序对 CDQ分治

动态逆序对 CDQ分治 传送门:https://www.luogu.org/problemnew/show/P3157 题意: 对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数。 题解: 这个题是告诉你如何将一个问题转换为三维偏序问题 首先,求解逆序对,...

weixin_30849403的博客 90
上一篇: 【详解】树状数组
下一篇: 【题解】[POJ 2352] Stars(树状数组)
_BOSS_
博客等级 码龄9年 22粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值