这道题让我们模拟冒泡排序,求交换次数,本质上是求序列的逆序对个数。 我们有两种方法求解——归并排序和树状数组。 【归并排序】 program Brainman; const maxn=1005; inf=10000000; msg='Scenario #'; type arr=array[0..maxn] of longint; var data:arr; n,ans:longint; flag:boolean; procedure prework; begin ans:=0; end; procedure init; var i:longint; begin read(n); for i:=1 to n do read(data[i]); end; procedure mergeit(left,mid,right:longint; var data:arr); var b,c:arr; i,j,k,nb,nc:longint; begin nb:=mid+1-left; nc:=right-mid; for i:=left to mid do b[i+1-left]:=data[i]; for i:=mid+1 to right do c[i-mid]:=data[i]; b[nb+1]:=inf; c[nc+1]:=inf; i:=1; j:=1; for k:=left to right do if b[i]<=c[j] then begin data[k]:=b[i]; inc(i); end else begin data[k]:=c[j]; inc(ans,nb+1-i); inc(j); end; end; procedure msort(left,right:longint; var data:arr); var mid:longint; begin if left<>right then begin mid:=(left+right) shr 1; msort(left,mid,data); msort(mid+1,right,data); mergeit(left,mid,right,data); end; end; procedure outit(i:longint); begin if flag then writeln else flag:=true; writeln(msg,i,':'); writeln(ans); end; procedure bigmain; var i,t:longint; begin readln(t); flag:=false; for i:=1 to t do begin prework; init; msort(1,n,data); outit(i); end; end; begin assign(input,'a.in'); reset(input); assign(output,'a.out'); rewrite(output); bigmain; close(input); close(output); end. 【树状数组】 program Brainman; const maxn=2000005; anum=1000002; msg='Scenario #'; var c:array[0..maxn] of longint; n,ans:longint; flag:boolean; function lowbit(x:longint):longint; begin exit(x and (-x)); end; procedure add(x:longint); begin while x<=maxn do begin inc(c[x]); inc(x,lowbit(x)); end; end; function sum(x:longint):longint; begin sum:=0; while x>0 do begin inc(sum,c[x]); dec(x,lowbit(x)); end; end; procedure prework; begin ans:=0; fillchar(c,sizeof(c),0); end; procedure init; begin read(n); end; procedure main; var i,w:longint; begin for i:=1 to n do begin read(w); inc(w,anum); add(w); inc(ans,sum(maxn)-sum(w)); end end; procedure outit(i:longint); begin if flag then writeln else flag:=true; writeln(msg,i,':'); writeln(ans); end; procedure bigmain; var i,t:longint; begin readln(t); flag:=false; for i:=1 to t do begin prework; init; main; outit(i); end; end; begin assign(input,'a.in'); reset(input); assign(output,'a.out'); rewrite(output); bigmain; close(input); close(output); end.