码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ3190[JLOI2013]赛车

时间:2017-01-08 19:12:12      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:open   desc   开始   array   包括   sizeof   int   gif   one   

Description

这里有一辆赛车比赛正在进行,赛场上一共有N辆车,分别称为个g1,g2……gn。赛道是一条无限长的直线。最初,gi位于距离起跑线前进ki的位置。比赛开始后,车辆gi将会以vi单位每秒的恒定速度行驶。在这个比赛过程中,如果一辆赛车曾经处于领跑位置的话(即没有其他的赛车跑在他的前面),这辆赛车最后就可以得奖,而且比赛过程中不用担心相撞的问题。现在给出所有赛车的起始位置和速度,你的任务就是算出那些赛车将会得奖。

Input

第一行有一个正整数N表示赛车的个数。
接下来一行给出N个整数,按顺序给出N辆赛车的起始位置。
再接下来一行给出N个整数,按顺序给出N辆赛车的恒定速度。

Output

输出包括两行,第一行为获奖的赛车个数。
第二行按从小到大的顺序输出获奖赛车的编号,编号之间用空格隔开,注意最后一个编号后面不要加空格。

Sample Input

4
1 1 0 0
15 16 10 20

Sample Output

3
1 2 4

HINT

对于100%的数据N<=10000, 0<=ki<=10^9, 0<=vi<=10^9

 

题解:

设位置为yi,yi=ki+ti*v,将其看作是y关于t的一次函数图像,毫无疑问,T时刻领先的赛车就是t=T时yi最大的函数。

这样,原题就变成了半平面交的模型,解法同BZOJ1007[HNOI2008]水平可见直线。

 

代码:

技术分享
var
  i,j,l,r,n,m:longint;
  k,b,a,s:array[0..10001]of longint;
  v:array[0..10001]of boolean;
  flag:boolean;
procedure sort(l,r:longint);
var
  i,j,x,x2,y:longint;
begin
  i:=l; j:=r; x:=k[(l+r)div 2]; x2:=b[(l+r)div 2];
  repeat
    while(k[i]<x)or((k[i]=x)and(b[i]<x2))do inc(i);
    while(x<k[j])or((x=k[j])and(x2<b[j]))do dec(j);
    if i<=j then
    begin
      y:=k[i]; k[i]:=k[j]; k[j]:=y;
      y:=b[i]; b[i]:=b[j]; b[j]:=y;
      y:=a[i]; a[i]:=a[j]; a[j]:=y;
      inc(i); dec(j);
    end;
  until i>j;
  if i<r then sort(i,r);
  if j>l then sort(l,j);
end;
begin
  readln(n);
  for i:=1 to n do read(b[i]);
  for i:=1 to n do read(k[i]);
  for i:=1 to n do a[i]:=i;
  sort(1,n);
  r:=1; i:=1;
  while(i<n)and(k[i]=k[i+1])and(b[i]<>b[i+1])do inc(i);
  s[1]:=i; inc(i); k[0]:=-1;
  while i<=n do
  begin
    while(r>0)and(k[i]=k[s[r]])and(b[i]<>b[s[r]])do dec(r);
    if k[i]<>k[s[r]] then
    begin
      while(r>0)and((b[i]-b[s[r]])/(k[s[r]]-k[i])<0)do dec(r);
      while(r>1)and((b[i]-b[s[r]])/(k[s[r]]-k[i])<
      (b[s[r]]-b[s[r-1]])/(k[s[r-1]]-k[s[r]])) do dec(r);
    end;
    inc(r); s[r]:=i; inc(i);
  end;
  fillchar(v,sizeof(v),false);
  writeln(r);
  for i:=1 to r do v[a[s[i]]]:=true;
  flag:=false;
  for i:=1 to n do
  if v[i] then
  begin
    if not flag then
    begin
      flag:=true; write(i);
    end else write( ,i);
  end;
  writeln;
end.
View Code

BZOJ3190[JLOI2013]赛车

标签:open   desc   开始   array   包括   sizeof   int   gif   one   

原文地址:http://www.cnblogs.com/GhostReach/p/6262478.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!