Link
\((a,b),(c,d)\)为基建系,并将原来的原点也加入序列,那么题目就转化为打乱顺序之后找一个最长的\(x,y\)坐标都单调上升的子序列。
\(x\)坐标为第一关键字,\(y\)坐标为第二关键字降序排序,题目就转化为了找以原来的原点为结束位置的LDS,离散化后BIT维护即可。

#include<cstdio>
#include<cctype>
#include<numeric>
#include<algorithm>
using i64=long long;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
const int N=100007;
struct node{i64 x,y;}p[N],q[N];
i64 h[N];int n,id[N],t[N];
void add(int p,int v){for(;p<=n;p+=p&-p)t[p]=std::max(t[p],v);}
int ask(int p){int r=0;for(;p;p^=p&-p)r=std::max(r,t[p]);return r;}
int main()
{
    n=read();int a=read(),b=read(),c=read(),d=read();
    for(int i=1,x,y;i<=n;++i) x=read(),y=read(),p[i]={x,y},q[i]={1ll*b*y-1ll*a*x,h[i]=1ll*d*y-1ll*c*x};
    ++n,std::iota(id+1,id+n+1,1),std::sort(h+1,h+n+1),std::sort(id+1,id+n+1,[](int i,int j){return q[i].x>q[j].x||(q[i].x==q[j].x&&q[i].y>q[j].y);});
    for(int i=1;i<=n;++i) q[i].y=std::lower_bound(h+1,h+n+1,q[i].y)-h;
    for(int j=1,i;i=id[j],j<=n;add(q[i].y,ask(q[i].y-1)+1),++j) if(!p[i].x&&!p[i].y) return !printf("%d",ask(q[i].y-1));
}

相关文章:

  • 2022-12-23
  • 2022-01-04
  • 2021-08-02
  • 2022-12-23
  • 2021-08-08
  • 2022-01-22
  • 2021-11-27
  • 2021-07-27
猜你喜欢
  • 2021-05-21
  • 2022-03-10
  • 2022-12-23
  • 2021-08-16
  • 2022-12-23
  • 2021-12-06
  • 2022-01-18
相关资源
相似解决方案