Description
休息的时候,可以放松放松浑身的肌肉,打扫打扫卫生,感觉很舒服。在某一天,某LMZ 开始整理他那书架。已知他的书有n 本,从左到右按顺序排列。他想把书从矮到高排好序,而每一本书都有一个独一无二的高度Hi。他排序的方法是:每一次将所有的书划分为尽量少的连续部分,使得每一部分的书的高度都是单调下降,然后将其中所有不少于2 本书的区间全部翻转。重复执行以上操作,最后使得书的高度全部单调上升。可是毕竟是休息时间,LMZ 不想花太多时间在给书排序这种事上面。因此他划分并翻转完第一次书之后,他想计算,他一共执行了多少次翻转操作才能把所有的书排好序。LMZ 惊奇地发现,第一次排序之前,他第一次划分出来的所有区间的长度都是偶数。
Input
第一行一个正整数n, 为书的总数。
接下来一行n个数,第i个正整数Hi,为第i 本书的高度。
接下来一行n个数,第i个正整数Hi,为第i 本书的高度。
Output
仅一个整数,为LMZ 需要做的翻转操作的次数。
Solutions
就是求逆序对。
代码
1 var 2 n:longint; 3 ans:int64; 4 a,b,sum:array[0..100001] of longint; 5 procedure swap(l,r:longint); 6 var 7 i:longint; 8 begin 9 for i:=l to r do 10 b[i]:=a[r-i+l]; 11 for i:=l to r do 12 a[i]:=b[i]; 13 end; 14 15 function low(x:longint):longint; 16 begin 17 exit(x and -x); 18 end; 19 20 procedure init; 21 var 22 i:longint; 23 begin 24 readln(n); 25 for i:=1 to n do 26 read(a[i]); 27 end; 28 29 procedure main; 30 var 31 i,j,l,mi:longint; 32 begin 33 l:=1; ans:=0; 34 mi:=maxlongint; 35 for i:=1 to n do 36 if a[i]>mi then 37 begin 38 if l<>i-1 then ans:=ans+1; 39 swap(l,i-1); 40 mi:=a[i]; 41 l:=i; 42 end else mi:=a[i]; 43 if l<n then 44 begin 45 ans:=ans+1; 46 swap(l,n); 47 end; 48 for i:=n downto 1 do 49 begin 50 j:=a[i]; 51 while j>0 do 52 begin 53 ans:=ans+sum[j]; 54 j:=j-low(j); 55 end; 56 j:=a[i]; 57 while j<=n do 58 begin 59 sum[j]:=sum[j]+1; 60 j:=j+low(j); 61 end; 62 end; 63 end; 64 65 begin 66 init; 67 main; 68 writeln(ans); 69 end.