HDU 4911 Inversion(树状数组求逆序对数 + 数据离散化)
2017-08-17 15:05
387 查看
[align=left]Problem Description[/align]
bobo has a sequence a1,a2,…,an. He is allowed to swap twoadjacent numbers for no more than k times.
Find the minimum number of inversions after his swaps.
Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and ai>aj.
[align=left]Input[/align]
The input consists of several tests. For each tests:
The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
[align=left]Output[/align]
For each tests:
A single integer denotes the minimum number of inversions.
[align=left]Sample Input[/align]
3 1
2 2 1
3 0
2 2 1
[align=left]Sample Output[/align]
1
2
题目大意:给定 n 个数,和最多 k 次的调整,每次只能选择交换相邻的两个数,问最少能得到的逆序对的个数。
观察一下不难发现交换任意一对最多减少一个逆序对,不影响其他部分,那么思路及很简单了。求出逆序对的个数,减 k 即可,需要注意的是,k 大于原串逆序对个数时直接输出零就行。
求逆序对我是用树状数组写的,所以对数据离散化了一下,也可以用分治的思想直接求。
代码如下:
bobo has a sequence a1,a2,…,an. He is allowed to swap twoadjacent numbers for no more than k times.
Find the minimum number of inversions after his swaps.
Note: The number of inversions is the number of pair (i,j) where 1≤i<j≤n and ai>aj.
[align=left]Input[/align]
The input consists of several tests. For each tests:
The first line contains 2 integers n,k (1≤n≤105,0≤k≤109). The second line contains n integers a1,a2,…,an (0≤ai≤109).
[align=left]Output[/align]
For each tests:
A single integer denotes the minimum number of inversions.
[align=left]Sample Input[/align]
3 1
2 2 1
3 0
2 2 1
[align=left]Sample Output[/align]
1
2
题目大意:给定 n 个数,和最多 k 次的调整,每次只能选择交换相邻的两个数,问最少能得到的逆序对的个数。
观察一下不难发现交换任意一对最多减少一个逆序对,不影响其他部分,那么思路及很简单了。求出逆序对的个数,减 k 即可,需要注意的是,k 大于原串逆序对个数时直接输出零就行。
求逆序对我是用树状数组写的,所以对数据离散化了一下,也可以用分治的思想直接求。
代码如下:
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int maxn = 1e5 + 5; ll t[maxn],sub[maxn],a[maxn]; bool vis[maxn]; int n; int lowbit(int x) { return x & -x; } ll query(int x) { ll sum = 0; while(x > 0) { sum += t[x]; x -= lowbit(x); } return sum; } void add(int x,int v) { while(x <= n) { t[x] += v; x += lowbit(x); } } int main() { int k; ll sum; while(scanf("%d %d",&n,&k) != EOF) { sum = 0; memset(t,0,sizeof(t)); memset(vis,false,sizeof(vis)); for(int i = 0;i < n; ++i) scanf("%d",&a[i]),sub[i] = a[i]; sort(sub,sub + n); int len = unique(sub,sub + n) - sub; for(int i = 0;i < n; ++i) { a[i] = lower_bound(sub,sub + len,a[i]) - sub + 1; } for(int i = 0;i < n; ++i) { sum += (query(n) - query(a[i])); add(a[i],1); } printf("%lld\n",k > sum ? 0 : sum - k); } return 0; }
相关文章推荐
- HDU - 4911 - Inversion(树状数组逆序数+离散化)
- Inversion (hdu 4911 树状数组 || 归并排序 求逆序对)
- 【树状数组】hdu 4911 Inversion(离散化+树状数组求逆序数)
- HDU 1394 Minimum Inversion Number (离散化 + 树状数组 求逆序对)
- HDU 1394 Minimum Inversion Number (树状数组求逆序对)
- HDU 4911 Inversion 树状数组求逆序数对
- HDU 5497 Inversion(树状数组求逆序对)
- SGU 180-Inversions(树状数组离散化求逆序对数)
- hdu 4911 Inversion(归并排序求逆序对数)2014多校训练第5场
- Hdu 1394 Minimum Inversion Number 树状数组求逆序对
- hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)
- 离散化+树状数组 求逆序对数
- HDU 4911 Inversion 树状数组求逆序数对
- poj2299 Ultra-QuickSort&&NYOJ117 求逆序数 (树状数组求逆序对数+离散化)+(归并排序)
- hdu 1394 Minimum Inversion Number (树状数组 逆序对)
- poj 2299 树状数组求逆序对数+离散化
- hdu 4911 Inversion(归并排序求逆序对数)2014多校训练第5场
- HDU 4911 - Inversion(树状数组||归并排序)
- [hdu]1394 Minimum Inversion Number -- 暴力求逆序、树状数组求逆序、线段树求逆序、归并排序求逆序
- hdu 5497 Inversion 求逆序对 树状数组