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 ...
随机推荐
- linux 三剑客之awk总结
AWK 1.begin end使用 cat /tmp/passwd |awk -F ':' 'BEGIN {print "hello"} {print $1"\t&quo ...
- 平面割线平分点(构造)--牛客第三场-- Magic Line
题意: 给你n个点的坐标,让你给出两个点,这两个点的连线可以平分这些点. 思路: 先按y的大小排序,在按x的小排序,再搞一下就行了.如下图: #include <bits/stdc++.h> ...
- JavaScript使用readAsDataURL读取图像文件
JavaScript使用readAsDataURL读取图像文件 FileReader对象的readAsDataURL方法可以将读取到的文件编码成Data URL.Data URL是一项特殊的技术,可以 ...
- 如何实现一个简化版的 jQuery
对于操作 DOM 来说,jQuery 是非常方便的一个库,虽然如今随着 React, Vue 之类框架的流行,jQuery 用得越来越少了,但是其中很多思想还是非常值得我们学习的,这篇文章将介绍如何从 ...
- Encryption (hard) CodeForces - 958C3 (树状数组)
大意: 给定序列$a$, 要求将$a$分成$k$个非空区间, 使得区间和模$p$的和最小, 要求输出最小值. $k$和$p$比较小, 直接暴力$dp$, 时间复杂度是$O(nklogp)$, 空间是$ ...
- 使用zookeeper报错 stat is not executed because it is not in the whitelist. envi is not executed because it is not in the whitelist.
在使用四字命令或者zk ui界面查看zookeeper集群时,出现如下提示: stat is not executed because it is not in the whitelist. envi ...
- Java基础(那些习以为常缺不知道原理的地方)
一.基础 1.1 正确的使用equals方法 Object的equals方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals.如下代码 // 不能使用一个值为null的引用类型变量来调 ...
- [转载]布隆过滤器(Bloom Filter)
[转载]布隆过滤器(Bloom Filter) 这部分学习资料来源:https://www.youtube.com/watch?v=v7AzUcZ4XA4 Filter判断不在,那就是肯定不在:Fil ...
- ISO/IEC 15444-12 MP4 封装格式标准摘录 2
目录 Track Media Structure Media Box Media Header Box Handler Reference Box Media Information Box Medi ...
- pthread_cond_wait
while(1) 33 { 34 mm* p = NULL; 35 pthread_mutex_lock(&mutex); 36 while(head == NULL) 37 pthread_ ...