【树状数组】hdu 4911 Inversion(离散化+树状数组求逆序数)
2017-07-19 14:36
405 查看
Inversion
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 4183 Accepted Submission(s): 1525
[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次,求交换后最小的逆序数是多少
分析:如果逆序数大于0,则存在1 ≤ i < n,使得交换ai和ai+1后逆序数减1。所以最后的答案就是max((inversion-k), 0)。利用树状数组求出原序列的逆序对数就可以解决问题了
注意:
因为数据比较大,因此肯定要用sort先排序 问题就在于相等的数怎么处理 如果你用的sort,就算你cmp里设定了相等的数不交换, 他也会交换?为什么?因为快排是不稳定的排序算法。 因此只用sort肯定会WA 别问我怎么知道的.....WA了一亿发... = = 解决办法用2个,一个使用stable_sort,这个跟sort用法一样, 但绝对不会改变相同的数的顺序 另外一个办法就是把相同的数字合并,或者说是删去计算即可
///AC代码(stable_sort版)
#include <iostream> #include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <bitset> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <algorithm> #include <functional> #define PI acos(-1) #define eps 1e-8 #define inf 0x3f3f3f3f #define debug(x) cout<<"---"<<x<<"---"<<endl typedef long long ll; using namespace std; const int N = 5e5 + 10; struct node { int val; int pos; } p ; int n, k, a , c ; bool cmp(const node&a, const node& b) { return a.val < b.val; } int lowbit(int x) { return x & (-x); } ///单点修改+区间求和 inline int sum(int x) { int res = 0; while (x) { res += c[x], x -= lowbit(x); } return res; } inline void add(int x) ///单点修改 { while (x <= n) { c[x] += 1, x += lowbit(x); } } inline int query(int x, int y)///区间求和 { return sum(y) - sum(x - 1); } int main() { while (scanf("%d%d", &n, &k) != EOF) { for (int i = 1; i <= n; i++) { scanf("%d", &p[i].val); p[i].pos = i; } stable_sort(p + 1, p + n + 1, cmp); ///排序 for (int i = 1; i <= n; i++) { a[p[i].pos] = i; ///离散化 } ll ans = 0; for (int i = 1; i <= n; i++)///初始化树状数组 { c[i] = 0; } for (int i = 1; i <= n; i++) { add(a[i]); ans += i - sum(a[i]); } if (ans - k < 0) { printf("0\n"); } else { printf("%lld\n", ans - k); } } return 0; }
///直接删除相同元素:
#include <iostream> #include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <bitset> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <algorithm> #include <functional> #define PI acos(-1) #define eps 1e-8 #define inf 0x3f3f3f3f #define debug(x) cout<<"---"<<x<<"---"<<endl typedef long long ll; using namespace std; const int N = 5e5 + 10; struct node { int val; int pos; } p ; int n, k, a , c ; bool cmp(const node&a, const node& b) { return a.val < b.val; } int lowbit(int x) { return x & (-x); } ///单点修改+区间求和 inline int sum(int x) { int res = 0; while (x) { res += c[x], x -= lowbit(x); } return res; } inline void add(int x) ///单点修改 { while (x <= n) { c[x] += 1, x += lowbit(x); } } inline int query(int x, int y)///区间求和 { return sum(y) - sum(x - 1); } int main() { while (scanf("%d%d", &n, &k) != EOF) { for (int i = 1; i <= n; i++) { scanf("%d", &p[i].val); p[i].pos = i; } //stable_sort(p + 1, p + n + 1, cmp); ///排序 sort(p + 1, p + n + 1, cmp); p[0].val = -1; int t = 0; for (int i = 1; i <= n; i++) { if (p[i].val != p[i - 1].val) { t++; } a[p[i].pos] = t; ///离散化 } ll ans = 0; for (int i = 1; i <= n; i++)///初始化树状数组 { c[i] = 0; } for (int i = 1; i <= n; i++) { add(a[i]); ans += i - sum(a[i]); } if (ans - k < 0) { printf("0\n"); } else { printf("%lld\n", ans - k); } } return 0; }
相关文章推荐
- HDU 4911 Inversion 树状数组求逆序数对
- HDU - 4911 - Inversion(树状数组逆序数+离散化)
- HDU 4911 Inversion(树状数组求逆序对数 + 数据离散化)
- hdu 4911 Inversion 树状数组求逆序数对
- HDU 4911 Inversion 树状数组求逆序数对
- hdu 1394 Minimum Inversion Number(树状数组求逆序数)
- HDU 1394 Minimum Inversion Number (树状数组求逆序数)
- hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)
- hdu1394 Minimum Inversion Number(树状数组求逆序数)
- Inversion (hdu 4911 树状数组 || 归并排序 求逆序对)
- hdu 1394 Minimum Inversion Number 树状数组求逆序数对(原理)
- hdu 1394 Minimum Inversion Number (树状数组求逆序数)
- HDU 1394 Minimum Inversion Number (离散化 + 树状数组 求逆序对)
- hdu 1394 Minimum Inversion Number(树状数组求逆序数)
- 【2014 Multi-University Training Contest 5】 Inversion (离散化,树状数组求逆序数)
- hdu Minimum Inversion Number---树状数组求正序数与逆序数
- 树状数组求正序数与逆序数-hdu Minimum Inversion Number
- HDU 1394 - Minimum Inversion Number(树状数组求逆序数)
- 树状数组求正序数与逆序数-hdu Minimum Inversion Number
- HDU 4911 - Inversion(树状数组||归并排序)