这里给大家提供一个全新的求逆序对的方法

是通过树状数组来实现的

题目描述

 

样例输入 Copy

5
2 3 1 5 4

样例输出 Copy

3

提示

 
 
 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstring>
using namespace std;
struct lisan{long long val,index;
};
lisan a[100005];
long long C[100005];
int nn;
int cmp1(lisan a,lisan b){if(a.val==b.val)return a.index<b.index;//sort的不稳定性//因为再下一次是按照下标再排回来,所以如果有数值相等的数,原来的下标先后顺序不能改变,否则会出现一些玄学错误return a.val<b.val;
}
int cmp2(lisan a,lisan b){return a.index<b.index;
}int lowbit(int x){return x&(-x);
}
void add(int x,int d){while(x<=nn){C[x]+=d;x+=lowbit(x);}//修改是从左往右
}
long long sum(int x){long long ret=0;while(x>0){ret+=C[x];x-=lowbit(x);//求和是从右往左
    }return ret;
}
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i].val;a[i].index=i;}//数据离散化模式开始 sort(a+1,a+n+1,cmp1);int x=0;for(int i=1;i<=n;i++){if(a[i].val==a[i-1].val)a[i].val=x;elsea[i].val=++x;}nn=x;sort(a+1,a+n+1,cmp2);//开始前缀和long long ans=0;for(int i=n;i>=1;i--){add(a[i].val,1);ans+=sum(a[i].val-1);} cout<<ans;return 0;
}

思路讲解:
假如有8个数,
a:1 3 2 4 3 1 2 4
从后往前扫
设一个数组分别表示从后往前扫当前每个数值一共出现了几次
一开始是这样的,扫最后一个4
b:0 0 0 1
b[4]之前全是0,所以ans=0+0+0 这里的前缀和用树状数组就可以
再扫2
b:0 1 0 1       b[2]之前全是0
再扫1
b:1 1 0 1     b[1]之前还是0
再扫3
1 1 1 1     终于b[3]之前1+1=2意思也就是之前的两个1,代表已经扫过的1、2分别出现了一次
也就是说,在a数组中,a[5]后比3小的一共有两个
如此往下。。。。。
但是这一题每一个数的最大值是10的九次方,要是开数组的话就炸了
但是数的个数最多只有100000
所以可用数据离散化
先从小到大排序
都压成1,2,3.。。。
至于数据离散化是什么呢
就是比如原来有一组数1 2 45 67568684 3252 653357.
因为数据范围较大,但是数的个数却不是很大
但是如果有的数太大有的数太小
就会不是非常方便
这样如果用这个数的数值作为一个数组的下标,当然就方便多了
我们在使用的时候只看重数与数之间谁大谁小的关系
可以把上面的一行数缩成1 2 3 6 4 5

转载于:https://www.cnblogs.com/Tidoblogs/p/10887694.html

Tido 习题-二叉树-树状数组求逆序对相关推荐

  1. 牛客练习赛33 D tokitsukaze and Inverse Number (树状数组求逆序对,结论)

    链接:https://ac.nowcoder.com/acm/contest/308/D 来源:牛客网 tokitsukaze and Inverse Number 时间限制:C/C++ 1秒,其他语 ...

  2. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分...

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

  3. 树状数组求逆序对_区间和的个数(树状数组)

    327. 区间和的个数 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper. 区间和 S(i, j) 表示在 nums 中,位置从 i ...

  4. 牛客 - What Goes Up Must Come Down(树状数组求逆序对)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,每次操作可以交换相邻两个数字的位置,现在问最小进行多少次操作,可以使得序列的相对大小呈山峰状(中间高两边低,或非严格递增或非严格递减) 题目分 ...

  5. 【Luogu1908】逆序对(离散化,树状数组求逆序对)

    problem 给你一个长为n的序列A[] 求该序列的逆序对个数 solution 用b[i]保存下标i在A中出现的次数,那么数组b[i]在[l,r]上的区间和,就表示序列A在范围[l,r]内的有多少 ...

  6. 树状数组求逆序对_初识树状数组

    树状数组是用来解决数列多次单点修改和前缀和查询的利器. 首先我们来看问题的原型: 已知一个长度为n(n<=10 0000)的数列,初始值都是零,现在我们要对数列施加两种类型的操作共q(q< ...

  7. 树状数组 求 逆序对

    如何统计第i个数与1-第i - 1个数构成多少个逆序对呢? 考虑根据值来建树状数组,初始树状数组为全0,先按序列从左到右将数据的值对应的位置的数加一,代表又有一个数出现.因此,在循环到第i项时,前i- ...

  8. 树状数组求逆序对_算法系列之-数组中的逆序对

    题目来源 剑指offer 01 题目描述 在数组中如果前一个数字大于后一个数字,则称为这个数字组合组成一个逆序对.输入一个数组,求所有的逆序对的总数. 如 数组 {7,5,6,4} 则它的逆序对是 ( ...

  9. [USACO17FEB] Why Did the Cow Cross the Road I P (树状数组求逆序对 易错题)

    题目大意:给你两个序列,可以序列进行若干次旋转操作(两个都可以转),对两个序列相同权值的地方连边,求最少的交点数 记录某个值在第一个序列的位置,再记录第二个序列中某个值 在第一个序列出现的位置 ,求逆 ...

最新文章

  1. MS SQL2005数据库备份
  2. .net运行项目的几种形式
  3. Editability on SAP Text
  4. 【转】深入理解JavaScript闭包(closure)
  5. 中国好声音不如有中国好创意
  6. _CrtCheckMemory
  7. java adt eclipse_在eclipse中添加android ADT
  8. 基于matlab的紧急疏散模型仿真的代码,基于matlab的疏散仿真程序简介.pdf
  9. 三星手机使用应用沙盒动态修改sdk数据
  10. 英语各类词担任的句子成分
  11. 微信程序开发小程序交互
  12. 计算机里的le是什么符号,在python中传递le或ge符号
  13. jQuery 特效:盒子破碎和移动动画效果
  14. (VDSR)Accurate Image Super-Resolution Using Very Deep Convolutional Networks——超分辨率(八)
  15. idea2021版本添加上一步和下一步操作到工具栏
  16. js将图片转base64两种方法
  17. 远程控制软件PcAnyWhere教程图解
  18. 高效编写简历项目经验,备受500强HR推荐的STAR法则
  19. 输出大写英文字母PTA
  20. Minecraft 1.18.1、1.18.2模组开发 15.自定义生成建筑(structure)

热门文章

  1. python 除法取模_Python的运算符和表达式(上)
  2. mysql配置日志老化配置_mysql中日志的配置与分析
  3. 广东计算机一级考试可以用计算器吗,你考试用不用计算器?
  4. Elasticsearch之深入了解Search的运行机制
  5. Spring boot定时任务(Scheduling Tasks)
  6. vscodemaven 配置_二、vscode搭建maven开发环境
  7. 作为一只Python爬虫:如何破解滑动验证码
  8. 刷新table数据_经典 - 一文轻松看懂数据透视表
  9. php css下划线,如何自定义下划线的样式
  10. sketch如何做设计稿交互_交互设计师是做什么的——交互设计的历史、现状和未来...