Description
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence
9 1 0 5 4 ,
Ultra-QuickSort produces the output
0 1 4 5 9 .
Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.
Input
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 – the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
Output
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
Sample Input
5
9
1
0
5
4
3
1
2
3
0
Sample Output
6
0
题意:求n个数经过冒泡排序变成有序后,交换的次数
线段树
记录每个数和它开始的位置pos,然后将它们排序,最后计算pos中有多少逆序对(类似于poj-3067-Japan)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define N 500005
#define ll long long
using namespace std;
int n;
ll ans[N];
struct node
{
int pos, num;
friend bool operator < (node a, node b)
{
return a.num < b.num;
}
}aaa[N];
void update(int x, int val)
{
while(x <= n)
{
ans[x] += val;
x += x&-x;
}
}
ll sum(int x)
{
ll ret = 0;
while (x > 0)
{
ret += ans[x];
x -= x&-x;
}
return ret;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
int i, j, K, T;
long long ret;
while(scanf("%d", &n), n)
{
ret = 0;
memset(ans, 0, sizeof(ans));
for (i = 0; i < n; i++)
{
scanf("%d", &aaa[i].num);
aaa[i].pos = 1+i;
}
sort(aaa, aaa+n);
for (i = 0; i < n; i++)
{
ret += sum(n)-sum(aaa[i].pos);
update(aaa[i].pos, 1);
}
printf("%lld\n", ret);
}
return 0;
}
归并排序
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define N 500010
using namespace std;
int n, a[N], t[N];
long long ans;
void Merg_Sort(int l, int r)
{
if (l >= r-1) return ;
int m = (l+r)>>1;
Merg_Sort(l, m);
Merg_Sort(m, r);
int p = l, q = m, i = l;
while(p < m || q < r)
{
if (q >= r || (p < m && a[p] < a[q])) t[i++] = a[p++];
else
{
if (p < m) ans += (m-p);
t[i++] = a[q++];
}
}
for (i = l; i < r; i++)
a[i] = t[i];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt", "r", stdin);
#endif
int i;
while(scanf("%d", &n), n)
{
memset(a, 0, sizeof(a));
memset(t, 0, sizeof(t));
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
ans = 0;
Merg_Sort(0, n);
printf("%lld\n", ans);
}
return 0;
}