冒泡排序的交换次数 (树状数组)
计算冒泡排序的交换次数:
逆序数概念:在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序
一个排列中所有逆序总数叫做这个排列的逆序数。 所以冒泡排序结束即是所有的逆序数为0
思路:
暴力:我们可以开一个vis[]数组记录 在遍历到第 i 位时,已经出现的值有哪些。然后遍历到 arr[i] (第i位的值),得到小于arr[i] 的出现个数(即 i<j && arr[i]<= arr[j]的个数)
然后再用当前长度 i 减去符合条件个数即得打 arr[i]的逆序个数。
优化:由于每次都要对小于 arr[i]的出现元素遍历,我们就希望能够开一个数组 记录arr[i]之前出现的符合条件个数(这样就不用每次都遍历一次取求)
那么对于单点更新,求区间和 ,我们就可以借助 树状数组 这个数据结构。所以就利用 树状数组进行优化。
操作:
求出数列种每一个数的逆序数求和
遍历a[i],a[i]再bit[i]中对应的值加一
记录每个值出现前小于自身,自身出现次数
遍历到j时a[j]前有j个数,即小于自身个数有bit[j]个
逆序数为 j - bit[j]
//计算冒泡排序的交换次数: //逆序数概念,冒泡排序结束即是所有的逆序数为0 //思路:求出数列种每一个数的逆序数求和 //遍历a[i],a[i]再bit[i]中对应的值加一 //记录每个值出现前小于自身,自身出现次数 //遍历到j时a[j]前有j个数,即小于自身个数有bit[j]个 //逆序数为 j - bit[j] #include <bits/stdc++.h> #define IOS ios::sync_with_stdio(0); cin.tie(0); #define mp make_pair #define Accept 0 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> pii; const double Pi = acos(-1.0); const double esp = 1e-9; const int inf = 0x3f3f3f3f; const int maxn = 1e5+7; const int maxm = 1e6+7; const int mod = 1e9+7; const int MAXL = 1e6+7;int n; int bit[maxn]; int arr[maxn]; int vis[maxn]; //求和即是从i开始,将其二进制最低位的1去掉,直到变为0 //前i项和 int sum(int i){int s = 0;while(i>0){s += bit[i];i -= i & -i;}return s; } //单点跟新,将第i位增加x,将最低为的非0幂加到对应的幂上 void add(int i,int x){//bit[i] = x; 单点修改//i += i & -i;while(i<=n){bit[i] += x;i += i & -i;} } void solve(){int ans = 0;for(int j = 0;j<n;j++){ans += j - sum(arr[j]);add(arr[j],1);}//暴力的解法 // for(int i=0;i<n;i++){ // int cnt = 0; // for(int j=0;j<arr[i];j++){ // if(vis[j]) cnt++; // } // ans += i - cnt; // vis[arr[i]] =1; // }printf("%d\n",ans); } int main(){memset(vis,0,sizeof(vis));scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&arr[i]);}solve();return 0; }
转载于:https://www.cnblogs.com/Tianwell/p/11490987.html
冒泡排序的交换次数 (树状数组)相关推荐
- 树状数组(求子区间和+更新元素值)
树状数组 欲完成修改值和查询区间和两种操作 求前缀和的做法时间复杂度为O(n)O(n)O(n) 使用树状数组时间复杂度降为O(logn)O(logn)O(logn) lowbit 1.x&(- ...
- Equalizing Two Strings 冒泡排序or树状数组
首先考虑排序后相等 如果排序后相等的话就只考虑reverse长度为2的,所以a或者b排序后存在相邻两个字母相等的话就puts YES,n>26也直接puts YES 不然的话就假设c为a,b排完 ...
- POJ 2299 Ultra-QuickSort(树状数组 + 离散)
链接:http://poj.org/problem?id=2299 题意:给出N个数组成的数列A(0 <= A[i] <= 999,999,999),求该数列逆序对的数量. 分析:题目所谓 ...
- CF362C Insertion Sort树状数组,思维,枚举
题意:先交换任意两个,然后只能交换相邻两个,问最少操作次数和方案. 思路:由于冒泡排序有个定理就是逆序数的个数等于最少的交换相邻元素的次数,问题就转换为了交换两个数并且使得整个数组逆序数个数最少,我们 ...
- 【学习笔记+习题集】(树状数组)(9473字)
目录 板块一:树状数组 引子:lowbit 1.存入数据(单点修改) 2.区间查询 练习1:hdoj1541 3.区间修改和单点查询(差分数组) 练习1:hdoj 1556 练习2:洛谷P3368 4 ...
- 【2018.12.15】【考试总结】【模拟+逆序对+树状数组+贪心+multiset】爆零之旅
这是我悲惨的接近爆零的一次考试,但是本蒟蒻不能放弃,还是要总结的QAQ 答题卡 [题目背景] 八月是个悲惨的月份.先不谈炎热的天气,对于新生来说,八月意味着军训: 而对于高二高三的同学来说,八月意味着 ...
- BZOJ 2141 排队(块套树,分块,树状数组)【BZOJ修复工程】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2141 是 hydro 的 BZOJ ...
- 【数据结构】树状数组 例题剖析
目录 一.模板题 二.树状数组求逆序对 一.离散化 二.逆序对 三.待解决 P1428 小鱼比可爱 算法详解 一.模板题 模板题 题目描述 如题,已知一个数列,你需要进行下面两种操作: 将某一个数加上 ...
- 树状数组 _ 求逆序数
注: 本文只是记录 ,您将从上面学习不到任何知识,除了 代码 (废话)第一次接触到树状数组,感觉接触到了新世界,理解这个思想用了好长时间,终于弄明白了(似懂非懂). 还有接触到了 离散化的思想, ...
最新文章
- 从底层吃透java内存模型(JMM)、volatile、CAS
- 你想了解的Cookie和Session就在这~
- 常见被病毒利用的漏洞补丁
- python基础类型,Python基础-类
- 操作系统中死锁避免算法 --- 银行家算法
- hive 时间函数_Hive常用大法(聚合/排序/分组)
- iOS应用内付费详解
- 指尖初体验之虚拟键盘
- 没有找到dllregisterserver输入点_「Mac实用技巧」将浏览器的点密码转换成文本密码的三种方法分享...
- 【Java进阶】Java并发包提供了哪些并发工具类?
- matlab 不确定度计算器,A类贝塞尔不确定度计算器下载
- 【我的Android进阶之旅】Android开发之NDK相关版本下载链接
- 红米pro android o刷机,红米Pro刷机工具稳定版
- 解决在RHEL/CentOS7.4以上版本无法使用AFD(Oracle ASMFD)特性
- B-JUI刷新当前标签页的方法
- 最佳适应(BestFit)算法
- 制药工程专业计算机考试考哪样,制药工程考研可以考什么专业
- Sass - 变量($)
- [硬件]电路-TTL
- 管理后台项目-04-SPU列表-增删改SPU-获取SKU【续】