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

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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值