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 ...
随机推荐
- 牛客 545C 出题人的数组 (贪心)
出题人有两个数组A,B,请你把两个数组归并起来使得$cost=\sum i c_i$最小. 归并要求原数组的数的顺序在新数组中不改变. 贪心水题 对于一段序列$A_i,A_{i+1},...,A_r$ ...
- ajax实现异步操作实例1
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- FreeBSD上编写x86 Shellcode初学者指南
FreeBSD上编写x86 Shellcode初学者指南 来源 https://www.4hou.com/binary/14375.html 介绍 本教程的目的是帮助你熟悉如何在FreeBSD操作系统 ...
- Ubuntu分区挂载
创建主分区: 25G 主分区 空间起始位置 Ext4日志文件系统 / (ps:安装主要放这了,原因不明) 创建swap分区: 8192MB 逻辑分区 空间起 ...
- [转载]C++STL—vector的插入与删除
来源:https://blog.csdn.net/duan19920101/article/details/50717748 vector::erase():从指定容器删除指定位置的元素或某段范围内的 ...
- Vue实例:vue2.0+ElementUI框架开发pc项目
开发前准备 vue.js2.0中文,项目所使用的js框架 vue-router,vue.js配套路由 vuex,状态管理 Element,UI框架 1,根据官方指引,构建项目框架 安装vue npm ...
- springboot访问出错,mapperScan导包错误java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.<init>() at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_172] at java.
2019-08-06 12:42:03.153 ERROR 10080 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Se ...
- 外网访问VMware(Centos7.0,NAT模式)搭建的web服务器应用
首先参考 https://www.cnblogs.com/studyhard-cq/p/11551755.html 设置好NAT模式,能访问公网. 1.打开VMware,点击左上角编辑 ...
- c++ 用模板类实现顺序储存的线性表
首先要注意的一点是模板类在VS中编译时如果将定义和声明分开会出现无法解析的问题,所以一般比较常见的解决的办法是将声明和定义放在同一个头文件中然后统一的调用,下面就是用模板类实现线性表的编写 #prag ...
- 简单了解TCP/IP与HTTP
这种东西网上资源非常丰富,完全没有必要造轮子,更何况 这也不是你能造的啊,来 上连接 TCP/IP https://www.runoob.com/tcpip/tcpip-intro.html HTTP ...