您的位置:首页 > 其它

NOIP提高A组集训第10场11.8 力场护盾

2016-11-08 20:49 330 查看
Description

ZMiG成功粉碎了707的基因突变计划,为了人类的安全,他决定向707的科学实验室发起进攻!707并没有想到有人敢攻击她的实验室,一时间不知所措,决定牺牲电力来换取自己实验室的平安。

在实验室周围瞬间产生了一个无限大的力场护盾,它看上去无懈可击!不过ZMiG拥有惊人的双向观察能力,经过他的反复观察,找到了这个护盾的N个弱点,他本想逐一击破,却发现一股神秘力量阻止了他的行为。原来他身处力场之中,受到了两股神秘力量的影响,这两股力量来自两个不同的方向并形成了一个小于180度的角,ZMiG每次可攻击的范围都受到这两个力的影响,当他攻击了点X之后,下一次可以攻击的点必须在以X为坐标原点的情况下,这两个力方向的夹角之间(包含边界)(具体意思可看样例)

ZMiG当然想打出一串最长的Combo,所以他想问问你最多可以攻击707弱点多少次

Input

第一行为一个整数N

第二行四个整数X1,Y1,X2,Y2,用来描述这两个力的方向,第一个力的方向为从原点向(X1,Y1)发射出的射线方向,第二个力的方向为原点向(X2,Y2)发射出的射线方向。保证两个方向不重合不反向,这两个方向小于180的夹角就是影响的方向

接下来N行,每行两个整数X,Y,代表一个弱点的坐标

Output

一个正整数代表ZMiG最多能攻击弱点多少次

Sample Input

5

3 1 1 3

2 1

1 4

3 4

5 6

5 2

Sample Output

3

Data Constraint

对于所有数据,-10^9<=X,Y,X1,Y1,X2,Y2<=10^9

对于 30%的数据, n<=1000

对于另外20%的数据,保证X1=1,Y1=0,X2=0,Y2=1

对于 100%的数据,n<=200000

Hint

样例解释:

最长的combo为 1->3->4

这题比赛的时候花费了好长时间,正确结论都推出来了结果没看见数据范围是负数。。。爆零了,,GG。具体做法是把所有坐标都投影到斜率之间的区间,其实就是求截距啦,然后直接二分求lis或者离散以后树状数组求lis都可以。。。

代码:

uses math;
type node=record
x,y:int64;
end;
var
i,j:longint;
k,p,n,m,x1,y1,x2,y2,maxlen,x,y:int64;
a:Array[0..1000000]of node;
g,f:array[0..1000000]of int64;
procedure qsort(l,r:longint);
var
i,j:longint;
t,m,m1:int64;
begin
i:=l;
j:=r;
m:=a[(l+r)div 2].x;
m1:=a[(l+r)div 2].y;
repeat
while (a[i].x<m)or((a[i].x=m)and(a[i].y<m1)) do inc(i);
while (a[j].x>m)or((a[j].x=m)and(a[j].y>m1)) do dec(j);
if i<=j then
begin
a[0]:=a[i];
a[i]:=a[j];
a[j]:=a[0];
inc(i);
dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end;
function ef(x:int64):int64;
var
i,j:longint;
l,r,mid,ret:int64;
begin
l:=1;
r:=maxlen;
ret:=0;
while l<=r do
begin
mid:=(l+r)div 2;
if g[mid]<=x then
begin
ret:=mid;
l:=mid+1;
end
else r:=mid-1;
end;
exit(ret);
end;
begin
assign(input,'shield.in');
assign(output,'shield.out');
reset(input);
rewrite(output);
readln(n);
readln(x1,y1,x2,y2);
for i:=1 to n do
begin
readln(x,y);
a[i].y:=(x1*y-y1*x);
a[i].x:=(y2*x-x2*y);
end;
qsort(1,n);
maxlen:=0;
fillchar(g,sizeof(g),$7f);
for i:=1 to n do
begin
f[i]:=ef(a[i].y)+1;
maxlen:=max(maxlen,f[i]);
g[f[i]]:=min(g[f[i]],a[i].y);
end;
writeln(maxlen);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二分 几何