AcWing 107. 超快速排序(归并排序 + 逆序对 or 树状数组)
在这个问题中,您必须分析特定的排序算法----超快速排序。
该算法通过交换两个相邻的序列元素来处理n个不同整数的序列,直到序列按升序排序。
对于输入序列9 1 0 5 4,超快速排序生成输出0 1 4 5 9。
您的任务是确定超快速排序需要执行多少交换操作才能对给定的输入序列进行排序。
输入格式
输入包括一些测试用例。
每个测试用例的第一行输入整数n,代表该用例中输入序列的长度。
接下来n行每行输入一个整数aiai,代表用例中输入序列的具体数据,第i行的数据代表序列中第i个数。
当输入用例中包含的输入序列长度为0时,输入终止,该序列无需处理。
输出格式
对于每个需要处理的输入序列,输出一个整数op,代表对给定输入序列进行排序所需的最小交换操作数,每个整数占一行。
数据范围
0≤N<5000000≤N<500000,
0≤ai≤9999999990≤ai≤999999999
输入样例:
5
9
1
0
5
4
3
1
2
3
0
输出样例:
6
0
算法:归并排序 + 逆序对 or 树状数组
题解:求最少的交换次数,其实就是求当前这个序列的逆序数。
归并排序 + 逆序对:
#include <iostream>
#include <cstdio> using namespace std; typedef long long ll; const int maxn = 5e5+; ll arr[maxn], b[maxn];
ll ans; void merge_sort(ll *arr, int l, int mid, int r) {
int i = l, j = mid + ;
int k = ;
while(i <= mid || j <= r) {
if(j > r || (i <= mid && arr[i] <= arr[j])) {
b[k++] = arr[i++];
} else {
ans += mid - i + ;
b[k++] = arr[j++];
}
}
for(int i = ; i < k; i++) {
arr[l + i] = b[i];
}
} void merge(ll *arr, int l, int r) {
if(l < r) {
int mid = (l + r) >> ;
merge(arr, l, mid);
merge(arr, mid + , r);
merge_sort(arr, l, mid, r);
}
} int main() {
int n;
while(scanf("%d", &n) && n) {
for(int i = ; i <= n; i++) {
scanf("%lld", &arr[i]);
}
ans = ;
merge(arr, , n);
cout << ans << endl;
}
return ;
}
树状数组:
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <vector>
#include <algorithm> using namespace std; typedef long long ll; const int maxn = 5e5+; vector<int> v; int arr[maxn];
ll tree[maxn << ];
int size; int lowbit(int x) {
return x & (-x);
} int find(int x) {
return lower_bound(v.begin(), v.end(), x) - v.begin() + ;
} void update(int x, int val) {
while(x <= size) {
tree[x] += val;
x += lowbit(x);
}
} ll getSum(int x) { //求出前面有多少个小于或等于x的数
ll res = ;
while(x > ) {
res += tree[x];
x -= lowbit(x);
}
return res;
} int main() {
int n;
while(scanf("%d", &n) && n) {
memset(tree, , sizeof tree);
for(int i = ; i <= n; i++) {
scanf("%d", &arr[i]);
v.push_back(arr[i]);
}
sort(v.begin(), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
size = v.size();
ll ans = ;
for(int i = ; i <= n; i++) {
update(find(arr[i]), );
ans += i - getSum(find(arr[i])); //用总数减去小于或等于arr[i]的数,就是当前这个数的逆序数
}
cout << ans << endl;
}
return ;
}
AcWing 107. 超快速排序(归并排序 + 逆序对 or 树状数组)的更多相关文章
- Day2:T4求逆序对(树状数组+归并排序)
T4: 求逆序对 A[I]为前缀和 推导 (A[J]-A[I])/(J-I)>=M A[j]-A[I]>=M(J-I) A[J]-M*J>=A[I]-M*I 设B[]=A[]-M*( ...
- hdu 4911 求逆序对数+树状数组
http://acm.hdu.edu.cn/showproblem.php?pid=4911 给定一个序列,有k次机会交换相邻两个位置的数,问说最后序列的逆序对数最少为多少. 实际上每交换一次能且只能 ...
- 【BZOJ 3295】动态逆序对 - 分块+树状数组
题目描述 给定一个1~n的序列,然后m次删除元素,每次删除之前询问逆序对的个数. 分析:分块+树状数组 (PS:本题的CDQ分治解法见下一篇) 首先将序列分成T块,每一块开一个树状数组,并且先把最初的 ...
- Bzoj 3295: [Cqoi2011]动态逆序对 分块,树状数组,逆序对
3295: [Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2886 Solved: 924[Submit][Stat ...
- bzoj1831 逆序对 (dp+树状数组)
注意到,所有的-1应该是一个不降的序列,否则不会更优那就先求出来不是-1的的逆序对个数,然后设f[i][j]表示第i个-1放成j的前i个-1带来的最小逆序对数量这个可以树状数组来求 #include& ...
- P3157 [CQOI2011]动态逆序对(树状数组套线段树)
P3157 [CQOI2011]动态逆序对 树状数组套线段树 静态逆序对咋做?树状数组(别管归并QWQ) 然鹅动态的咋做? 我们考虑每次删除一个元素. 减去的就是与这个元素有关的逆序对数,介个可以预处 ...
- POJ2299逆序对模板(树状数组)
题目:http://poj.org/problem?id=2299 只能相邻两个交换,所以交换一次只会减少一个逆序对.所以交换次数就是逆序对数. ps:原来树状数组还可以记录后边lowbit位的部分和 ...
- 【Luogu】P3157动态逆序对(树状数组套主席树)
题目链接 md第一道在NOILinux 下用vim做的紫题.由于我对这个操作系统不是很熟悉,似乎有什么地方搞错了,md调死.(我还打了两遍代码,调了两个小时) 但是这道题并不难,就是树状数组套上主席树 ...
- BZOJ3295 动态逆序对(树状数组套线段树)
[Cqoi2011]动态逆序对 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 6058 Solved: 2117[Submit][Status][D ...
随机推荐
- Java第六周课堂示例总结
一.如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算? public class InitializeBlockDemo { /** * @param args */ pub ...
- 2019中山纪念中学夏令营-Day19 数论初步【GCD(最大公约数),素数相关】
关于GCD的一些定理或运用的学习: 1. 2.二进制算法求GCD 思想:使得最后的GCD没有2(提前把2提出来) 代码实现: #include <cstdio> #define int l ...
- jinja2介绍
jinja2介绍 jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用. jinja2的优点 jin ...
- CentOS 7 yum安装LAMP,LNMP并搭建WordPress个人博客网站
本次实验要进行的是在CentOS7.2,内核版本3.10.0-327.el7.x86_64的环境下搭建LAMP和LNMP,并在此之上做一个WordPress博客网站. [root@Shining ~] ...
- 在Windows下安装BIND作为DNS服务器(模拟网站比较有用)
本文参考了CU下的一篇帖子,感谢:) 1.下载BIND http://ftp.isc.org/isc/bind9/9.4.3/BIND9.4.3.zip 2.安装 下载回来是zip的压缩包,解压 ...
- 如何在Python中快速画图——使用Jupyter notebook的魔法函数(magic function)matplotlib inline
如何在Python中快速画图--使用Jupyter notebook的魔法函数(magic function)matplotlib inline 先展示一段相关的代码: #we test the ac ...
- Django框架——基础之模型系统(ORM的介绍和字段及字段参数)
1.ORM简介 1.1 ORM的概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM ...
- python爬去虎扑数据信息,完成可视化
首先分析虎扑页面数据 如图我们所有需要的数据都在其中所以我们获取需要的内容直接利用beaitifulsoupui4``` soup.find_all('a',class_ ...
- 关于spring读取配置文件的两种方式
很多时候我们把需要随时调整的参数需要放在配置文件中单独进行读取,这就是软编码,相对于硬编码,软编码可以避免频繁修改类文件,频繁编译,必要时只需要用文本编辑器打开配置文件更改参数就行.但没有使用框架之前 ...
- 基于mini2440嵌入式Linux根文件系统制作(Initramfs和nfs两种跟文件系统)
嵌入式系统由三部分构成: 1.bootoader---bootparameters---2.kernel 3.Root-filesysytem 一个内核可以挂载多个文件系统,但是有一个根文件系统所以叫 ...