树状数组优化 之 uva299
2014-04-07 21:04
155 查看
法1:树状数组优化 O(nlogn)
// [4/7/2014 Sjm]
/*
求解思路:
***所求的交换个数 <=> 满足 j<i, a[j]>a[i] 的个数***
若已知前 i-1 个数值中不大于 arr[i] 的数据个数为 bit[i].
则利用 (i-1)-bit[i] 即可求出 满足 j<i, a[j]>a[i] 的个数,
进而求出答案。
定义:
bit[i] := 查询的是前 arr[i] 项的和,
代表了在数组的前 i-1 个数值中不大于 arr[i] 的数据个数
(用数学语言描述就是:满足 j<i, arr[j]<=arr[i] 的数据个数)
*/
// [4/7/2014 Sjm]
/*
求解思路:
***所求的交换个数 <=> 满足 j<i, a[j]>a[i] 的个数***
若已知前 i-1 个数值中不大于 arr[i] 的数据个数为 bit[i].
则利用 (i-1)-bit[i] 即可求出 满足 j<i, a[j]>a[i] 的个数,
进而求出答案。
定义:
bit[i] := 查询的是前 arr[i] 项的和,
代表了在数组的前 i-1 个数值中不大于 arr[i] 的数据个数
(用数学语言描述就是:满足 j<i, arr[j]<=arr[i] 的数据个数)
*/
// 13461214 299 Train Swapping Accepted C++ 0.012 2014-04-07 12:30:44 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; typedef long long ll; const int MAX_N = 50; int bit[MAX_N + 1], n, arr[MAX_N]; int mySum(int i) { int sum = 0; while (i>0){ sum += bit[i]; i -= (i&(-i)); } return sum; } void myAdd(int i, int x) { while (i<=n) { bit[i] += x; i += (i&(-i)); } } ll Solve() { memset(bit, 0, sizeof(bit)); ll ans = 0; for (int i = 0; i < n; i++) { ans += (i - mySum(arr[i])); myAdd(arr[i], 1); } return ans; } int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); int T; scanf("%d", &T); for (int i = 1; i <= T; i++) { scanf("%d", &n); for (int j = 0; j < n; j++) scanf("%d", &arr[j]); printf("Optimal train swapping takes %lld swaps.\n", Solve()); } return 0; }法2:冒泡排序模拟 O(n^2) (由于n较小,亦可AC)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; typedef long long ll; const int MAX_N = 50; int arr[MAX_N], n; ll Solve() { ll ans = 0; int j = 0; bool myJudge; do { myJudge = false; for (int i = (n - 1); i > j; i--) { if (arr[i - 1] > arr[i]) { arr[i - 1] ^= arr[i]; arr[i] ^= arr[i - 1]; arr[i - 1] ^= arr[i]; myJudge = true; ans++; } } } while (myJudge && j<(n-1)); return ans; } int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); int T; scanf("%d", &T); for (int i = 1; i <= T; i++) { scanf("%d", &n); for (int j = 0; j < n; j++) scanf("%d", &arr[j]); printf("Optimal train swapping takes %lld swaps.\n", Solve()); } return 0; }
相关文章推荐
- 冒泡排序
- c++冒泡排序示例分享
- Java中的数组排序方式(快速排序、冒泡排序、选择排序)
- python冒泡排序算法的实现代码
- c#冒泡排序示例分享
- c语言冒泡排序法代码
- php排序算法(冒泡排序,快速排序)
- PHP 冒泡排序算法的实现代码
- 冒泡排序算法原理及JAVA实现代码
- java数组排序示例(冒泡排序、快速排序、希尔排序、选择排序)
- Java冒泡排序(Bubble Sort)实例讲解
- 用java实现冒泡排序算法
- 控制台显示java冒泡排序流程示例
- Java冒泡排序
- 冒泡排序法
- 2(1).选择排序_冒泡(线性表)
- 2(2).选择排序_冒泡(双向循环链表)
- 冒泡排序
- 冒泡排序
- 排序算法(快速排序、直接插入排序、直接选择、冒泡排序)