树状数组优化 之 uva299

法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] 的数据个数)

*/

 1 // 13461214    299    Train Swapping    Accepted    C++    0.012    2014-04-07 12:30:44
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 const int MAX_N = 50;
 9 int bit[MAX_N + 1], n, arr[MAX_N];
10 
11 int mySum(int i)
12 {
13     int sum = 0;
14     while (i>0){
15         sum += bit[i];
16         i -= (i&(-i));
17     }
18     return sum;
19 }
20 
21 void myAdd(int i, int x)
22 {
23     while (i<=n) {
24         bit[i] += x;
25         i += (i&(-i));
26     }
27 }
28 
29 ll Solve()
30 {
31     memset(bit, 0, sizeof(bit));
32     ll ans = 0;
33     for (int i = 0; i < n; i++)
34     {
35         ans += (i - mySum(arr[i]));
36         myAdd(arr[i], 1);
37     }
38     return ans;
39 }
40 
41 int main()
42 {
43     //freopen("input.txt", "r", stdin);
44     //freopen("output.txt", "w", stdout);
45     int T;
46     scanf("%d", &T);
47     for (int i = 1; i <= T; i++)
48     {
49         scanf("%d", &n);
50         for (int j = 0; j < n; j++)
51             scanf("%d", &arr[j]);
52         printf("Optimal train swapping takes %lld swaps.
", Solve());
53     }
54     return 0;
55 }

法2:冒泡排序模拟 O(n^2)  (由于n较小,亦可AC)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 using namespace std;
 6 typedef long long ll;
 7 const int MAX_N = 50;
 8 int arr[MAX_N], n;
 9 
10 ll Solve()
11 {
12     ll ans = 0;
13     int j = 0;
14     bool myJudge;
15     do 
16     {
17         myJudge = false;
18         for (int i = (n - 1); i > j; i--) {
19             if (arr[i - 1] > arr[i]) {
20                 arr[i - 1] ^= arr[i];
21                 arr[i] ^= arr[i - 1];
22                 arr[i - 1] ^= arr[i];
23                 myJudge = true;
24                 ans++;
25             }
26         }
27     } while (myJudge && j<(n-1));
28     return ans;
29 }
30 
31 int main()
32 {
33     //freopen("input.txt", "r", stdin);
34     //freopen("output.txt", "w", stdout);
35     int T;
36     scanf("%d", &T);
37     for (int i = 1; i <= T; i++)
38     {
39         scanf("%d", &n);
40         for (int j = 0; j < n; j++)
41             scanf("%d", &arr[j]);
42         printf("Optimal train swapping takes %lld swaps.
", Solve());
43     }
44     return 0;
45 }