冒泡排序的交换次数
来源:互联网 发布:2016香港经济发展数据 编辑:程序博客网 时间:2024/06/05 07:56
题意:
给定一个1~n的排列a0,a1,…an-1,求对这个数列进行冒泡排序所需要的交换次数(冒泡排序是每次找到满足ai>ai+1的i,并交换ai和ai+1,直到这样的i不存在为止的算法)。
限制条件:1<= n<= 100000
输入:
n=4, a={3,1,4,2}
输出:
3
冒泡排序的复杂度是O(n2),所有无法通过模拟冒泡排序的过程来计算需要的交换次数。不过我们可以通过选取适当的数据结构来解决这个问题。
首先,所求的交换次数等价于满足i<j,ai>aj的(i,j)数对的个数(这种数对的个数叫做逆序数)。而对于每一个j,如果能够快速求出满足i<j,ai>aj的i的个数,那么问题就迎刃而解。我们构建一个值得范围是1~n的BIT,按照j=0,1,2,…,n-1的顺序进行如下操作。
*把j-(BIT查询得到的前aj项的和)加到答案中
*把BIT中aj位置上的值加1
对于每一个j,(BIT查询得到的前aj项的和)就是满足i<j,ai<=aj的i的个数。因此把这个值从j中减去之后,得到的就是满足i<j,ai>aj的i的个数。由于对于每一个j的复杂度是O(logn),所以整个算法的复杂度是O(nlogn)。
#include <cstdio>using namespace std;typedef long long ll;const int maxn = 100000 + 10;int n;int a[maxn];int bit[maxn];int sum(int i){ int s = 0; while (i > 0){ s += bit[i]; i -= i & -i; } return s;}void add(int i, int x){ while (i <= n){ bit[i] += x; i += i & -i; }}void solve(){ ll ans = 0; for (int j = 0; j < n; j++){ ans += j - sum(a[j]); add(a[j], 1); } printf("%lld\n", ans);}int main(){ scanf("%d", &n); for (int i = 0; i < n; i++){ scanf("%d", &a[i]); } solve(); return 0;}
0 0
- 冒泡排序的交换次数
- 冒泡排序的交换次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 树状数组------冒泡排序的交换次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数
- 冒泡排序中数据交换的次数(sdu2554
- 178_冒泡排序的交换次数(逆序数)
- 冒泡排序中数据交换的次数 (sdut oj)
- SDUT-2554 冒泡排序中数据交换的次数
- 运用BIT处理冒泡排序的交换次数问题
- 树状数组应用-冒泡排序的交换次数
- サポートベクターマシン(SVM)
- python logging的简单使用2
- LeeCode-Insertion Sort List
- cuda7.0安装(嵌入式)
- iOS网络编程————POST请求和GET请求
- 冒泡排序的交换次数
- R语言实现文本挖掘和tagxedo词云可视化技术
- [JSOI2016]无界单词
- ニューラルネットワーク
- Python学习笔记11
- Anaconda 下各种第三方库的安装
- Linux 系统应用编程——进程基础
- 【Leetcode】:51. N-Queens 问题 in JAVA
- 爬山演算法