说的倒是挺悬乎的,但是仔细就不难发现这是一道求逆序对的题目。
可以发现,如果位于前面的汽车的速度比后面的汽车快那么就一定会有一次超车,因此我们首先需要一次排序,位置从前向后排一遍,然后用速度做一个归并排序就可以求出有多少对逆序对了。
program overtaking;
const
maxn=300000;
type
atp=record
loc,v:longint;
end;
var
ans:int64;
n:longint;
a:array [0..maxn] of atp;
v,temp:array [0..maxn] of longint;
procedure init;
var
i:longint;
begin
ans:=0;
readln(n);
for i:=1 to n do readln(a[i].loc,a[i].v);
end;
procedure qsort(l,r:longint);
var
i,j,m:longint;
t:atp;
begin
i:=l;
j:=r;
m:=a[(l+r) shr 1].loc;
repeat
while a[i].loc<m do inc(i);
while a[j].loc>m do dec(j);
if i<=j then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure merge(l,mid,r:longint);
var
i,j:longint;
begin
i:=l;
j:=mid+1;
while (i<=mid) and (j<=r) do
begin
if v[i]<=v[j] then
begin
temp[i+j-mid-1]:=v[i];
inc(i);
end
else
begin
temp[i+j-mid-1]:=v[j];
inc(j);
inc(ans,mid-i+1);
end;
end;
if i<=mid then
begin
while i<=mid do
begin
temp[i+j-mid-1]:=v[i];
inc(i);
end;
end;
if j<=r then
begin
while j<=r do
begin
temp[i+j-mid-1]:=v[j];
inc(j);
end;
end;
for i:=l to r do v[i]:=temp[i];
end;
procedure mergesort(l,r:longint);
var
mid:longint;
begin
if l<>r then
begin
mid:=(l+r) shr 1;
mergesort(l,mid);
mergesort(mid+1,r);
merge(l,mid,r);
end;
end;
procedure test;
var
i:longint;
begin
for i:=1 to n do v[i]:=a[i].v;
end;
begin
assign(input,'overtaking.in'); reset(input);
assign(output,'overtaking.out'); rewrite(output);
init;
qsort(1,n);
test;
mergesort(1,n);
writeln(ans);
close(input); close(output);
end.