题解 P1296 【奶牛的耳语】
其实这题有O(n)的做法的,用不到之前dalao说的二分啊之类的......
首先先把位置排序(我一开始以为是默认有序的,结果WA)
然后先处理第1头奶牛向右最多能让第几头奶牛听到,记录指针p,和答案ans
然后枚举每一头奶牛,因为排过序了,所以第1头奶牛能传出去的后面的奶牛肯定也能传到,只要在p的基础上继续向后扩展就可以了
注意一个特殊情况,如果一个奶牛不能向右传出去到任何一个奶牛(就是它后面的奶牛都离它巨远),这时候p要指向下一头奶牛,不然会出现p<枚举的i的情况,出现错误
Code(Pascal 福利!!):
var
ans:int64;
d,i,j,m,n,k,p:longint;
a:array[0..1000005]of longint;
procedure qs(l,r:longint);
var
i,j,mid,a1:longint;
begin
i:=l; j:=r;
mid:=a[(l+r) div 2];
repeat
while a[i]<mid do inc(i);
while a[j]>mid do dec(j);
if not(i>j) then
begin
a1:=a[i]; a[i]:=a[j]; a[j]:=a1;
inc(i); dec(j);
end;
until i>j;
if i<r then qs(i,r);
if l<j then qs(l,j);
end;
begin
readln(n,d);
for i:=1 to n do
read(a[i]);
qs(1,n);//好羡慕你们C++啊
for i:=2 to n do
begin
if a[i]-a[1]<=d then
inc(ans)
else
begin
p:=i-1; break;
end;
end;
for i:=2 to n do
begin
//ans:=ans+p-i;
while (p+1<=n)and(a[p+1]-a[i]<=d) do
inc(p);
ans:=ans+p-i;
if p=i then p:=i+1;
end;
writeln(ans);
end.