以前写过本题,现在写篇题解记录一下。
\(c_1(a_i-a_0)+c_2(b_i-b_0)\leqslant c_3 \iff c_1a_i+c_2b_i\leqslant c_3+c_1a_0+c_2b_0\)
左边是个常数,记为 \(c_i\)
考虑枚举 \(a_0,b_0\) 并将所有数按照 \(c\) 排序。
可以发现,\(a_0\) 相同, \(b_0\) 增大时只会不断向右,且一旦被删去,就不会再次被添加。
复杂度 \(\mathcal O(n^2)\)。
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
struct Ios{}io;
template <typename _tp>
Ios &operator >>(Ios &in,_tp &x){
x=0;int w=0;char c=getchar();
for(;!isdigit(c);w|=c=='-',c=getchar());
for(;isdigit(c);x=x*10+(c^'0'),c=getchar());
if(w) x=-x;
return in;
}
const int N=2005;
int a[N],b[N];
struct qwq{int pos,val;}c[N];
bool operator <(qwq x,qwq y){return x.val<y.val;}
int indb[N];
int rkb[N];
int t[N];
int main(){
int n,c1,c2,c3;io>>n>>c1>>c2>>c3;
for(int i=1;i<=n;++i)
io>>a[i]>>b[i],indb[i]=b[i],c[i].val=c1*a[i]+c2*b[i]-c3,c[i].pos=i;
int len=n;
sort(indb+1,indb+n+1);
len=unique(indb+1,indb+n+1)-indb-1;
sort(c+1,c+n+1);
for(int i=1;i<=n;++i) rkb[i]=lower_bound(indb+1,indb+len+1,b[i])-indb;
int ans=0;
for(int i=1;i<=n;++i){
int a0=a[i];
int r=0;
memset(t,0,sizeof(t));
int now=0;
for(int j=1;j<=len;++j){
int b0=indb[j],lim=a0*c1+b0*c2;
while(r<n&&c[r+1].val<=lim){
++r;
if(a[c[r].pos]>=a0&&b[c[r].pos]>=b0) ++now,++t[rkb[c[r].pos]];
}
now-=t[j-1];
ans=max(ans,now);
}
}
printf("%d\n",ans);
return 0;
}
标签:P1493,now,int,梨子,pos,indb,include,getchar
From: https://www.cnblogs.com/pref-ctrl27/p/16874948.html