您的位置:首页 > 其它

树状数组优化 之 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] 的数据个数)

*/

// 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息