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 output0 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
AC代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 500777;
struct Tree{
int l, r;
ll sum;
}tree[maxn << 2];
struct node{
ll val, pos;
}pos[maxn];
ll res = 0;
int n;
int x[maxn];
void build(int k, int l, int r)
{
tree[k].l = l;
tree[k].r = r;
if(tree[k].l == tree[k].r)
{
tree[k].sum = 0;
return ;
}
int m = (tree[k].l + tree[k].r) / 2;
build(2 * k, l, m);
build(2 * k + 1, m + 1, r);
tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
int cmp(struct node a, struct node b)
{
return a.val < b.val;
}
void change_point(int k, int pos)
{
if(tree[k].l == pos && tree[k].r == pos)
{
tree[k].sum = 1;
return ;
}
int m = (tree[k].l + tree[k].r) / 2;
if(pos <= m) change_point(2 * k, pos);
else change_point(2 * k + 1, pos);
tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
ll query(int k, int l, int r)
{
if(l > r)return 0;
if(tree[k].l == l && tree[k].r == r)
{
return tree[k].sum;
}
int m = (tree[k].l + tree[k].r) / 2;
if(l > m)
{
return query(2 * k + 1, l, r);
}
else if(r <= m)
{
return query(2 * k, l, r);
}
else
{
return query(2 * k, l, m) + query(2 * k + 1, m + 1, r);
}
}
int main()
{
while(scanf("%d", &n) != EOF && n)
{
build(1,1,n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &pos[i].val);
pos[i].pos = i;
}
sort(pos + 1, pos + n + 1, cmp);
for(int i = 1; i <= n; i++)
{
x[pos[i].pos] = i;
}
res = 0;
for(int i = 1; i <= n; i++)
{
res = res + x[i] - 1 - query(1,1,x[i] - 1);
change_point(1,x[i]);
}
cout<<res<<endl;
}
}
使用Map离散化,超时代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
typedef long long ll;
const int maxn = 500777;
struct Tree{
int l, r;
ll sum;
}tree[maxn << 2];
struct node{
ll val, pos;
}pos[maxn];
map<ll,ll> mp;
ll res = 0;
int n;
ll x;
int a[maxn], b[maxn];
void build(int k, int l, int r)
{
tree[k].l = l;
tree[k].r = r;
if(tree[k].l == tree[k].r)
{
tree[k].sum = 0;
return ;
}
int m = (tree[k].l + tree[k].r) / 2;
build(2 * k, l, m);
build(2 * k + 1, m + 1, r);
tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
int cmp(struct node a, struct node b)
{
return a.val < b.val;
}
void change_point(int k, int pos)
{
if(tree[k].l == pos && tree[k].r == pos)
{
tree[k].sum = 1;
return ;
}
int m = (tree[k].l + tree[k].r) / 2;
if(pos <= m) change_point(2 * k, pos);
else change_point(2 * k + 1, pos);
tree[k].sum = tree[2 * k].sum + tree[2 * k + 1].sum;
}
ll query(int k, int l, int r)
{
if(l > r)return 0;
if(tree[k].l == l && tree[k].r == r)
{
return tree[k].sum;
}
int m = (tree[k].l + tree[k].r) / 2;
if(l > m)
{
return query(2 * k + 1, l, r);
}
else if(r <= m)
{
return query(2 * k, l, r);
}
else
{
return query(2 * k, l, m) + query(2 * k + 1, m + 1, r);
}
}
int main()
{
while(scanf("%d", &n) != EOF && n)
{
build(1,1,n);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(int i = 1; i <= n; i++)
{
scanf("%lld", &x);
a[i] = x;
b[i] = x;
}
sort(b + 1,b + 1 + n);
for(ll i = 1; i <= n; i++)
{
mp[b[i]] = i;
}
res = 0;
for(int i = 1; i <= n; i++)
{
res = res + mp[a[i]] - 1 - query(1,1,mp[a[i]] - 1);
change_point(1,mp[a[i]]);
}
cout<<res<<endl;
}
}