POJ2299-Ultra-QuickSort

Ultra-QuickSort

 

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

这题是一道裸的求逆序对题,可以用树状数组或归并排序来求,可以当作树状数组的经典入门题。下面附上树状数组写法。

归并排序写法

Code:

var
  n,i:longint;ans:int64;
  a,p,tree:array[0..500000] of longint;
procedure sort(l,r:longint);
var i,j,x,y:longint;
begin
  i:=l;j:=r;x:=a[(l+r) div 2];
  repeat
    while (a[i]<x) do inc(i);
    while (a[j]>x) do dec(j);
    if not(i>j) then
    begin
      y:=a[i];a[i]:=a[j];a[j]:=y;
      y:=p[i];p[i]:=p[j];p[j]:=y;
      inc(i);dec(j);
    end;
  until i>j;
  if l<j then sort(l,j);
  if i<r then sort(i,r);
end;
procedure add(k:longint);
begin
  while k<=n do
  begin
    inc(tree[k]);
    k:=k+(k) and (-k);
  end;
end;
function sum(k:longint):longint;
var ans:longint;
begin
  ans:=0;
  while k>0 do
  begin
    ans:=ans+tree[k];
    k:=k-(k) and (-k);
  end;
  exit(ans);
end;
begin
  readln(n);
  while n<>0 do
  begin
    for i:=1 to n do
    begin
      read(a[i]);
      p[i]:=i;
    end;
    sort(1,n);
    ans:=0;
    for i:=1 to n do a[p[i]]:=i;
    fillchar(tree,sizeof(tree),0);
    for i:=1 to n do
    begin
      add(a[i]);
      ans:=ans+i-sum(a[i]);
    end;
    writeln(ans);
    readln(n);
  end;
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackflyDC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值