3462. 【NOIP2013模拟联考5】休息(rest) (Standard IO)

Description

休息的时候,可以放松放松浑身的肌肉,打扫打扫卫生,感觉很舒服。在某一天,某LMZ 开始整理他那书架。已知他的书有n 本,从左到右按顺序排列。他想把书从矮到高排好序,而每一本书都有一个独一无二的高度Hi。他排序的方法是:每一次将所有的书划分为尽量少的连续部分,使得每一部分的书的高度都是单调下降,然后将其中所有不少于2 本书的区间全部翻转。重复执行以上操作,最后使得书的高度全部单调上升。可是毕竟是休息时间,LMZ 不想花太多时间在给书排序这种事上面。因此他划分并翻转完第一次书之后,他想计算,他一共执行了多少次翻转操作才能把所有的书排好序。LMZ 惊奇地发现,第一次排序之前,他第一次划分出来的所有区间的长度都是偶数。
 

Input

第一行一个正整数n, 为书的总数。
接下来一行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.

猜你喜欢

转载自www.cnblogs.com/zyx-crying/p/9336521.html