Daxia & Yayamao's problem
FZU - 2239如果j>k,Aj>Ak,Aj*x+Bj>=Ak*x+Bk,则(Bj-Bk)/(Aj-Ak)>=-x
说明如果j要比k优,那么斜率一定要大于-x,根据斜率优化,这样就需要构建上凸包
构建完凸包后,再用三分找最优点即可
#include<cstdio>
#include<algorithm>
using namespace std;
const int MX = 1e5 + 5;
typedef long long LL;
struct node{
LL x,y;
node(){}
node(LL X,LL Y){x=X;y=Y;}
node operator-(node _A){
return node(x-_A.x,y-_A.y);
}
LL operator^(node _A){
return x*_A.y-y*_A.x;
}
}p[MX];
bool cmp(node p1,node p2){
if(p1.x!=p2.x) return p1.x<p2.x;
return p1.y<p2.y;
}
void convex(int &n){
int cnt=0;
for(int i=1;i<=n;i++){
while(cnt>=2&&((p[i]-p[cnt])^(p[cnt]-p[cnt-1]))<=0) cnt--;
p[++cnt]=p[i];
}
n=cnt;
}
LL f(int i,LL k){
return p[i].x*k+p[i].y;
}
int main(){
LL x;
int n,m;
// freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++) scanf("%I64d%I64d",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp);
convex(n); //构建凸包
for(int i=1;i<=m;i++){
scanf("%I64d",&x);
int l=1,r=n;
//三分找最优点
while(l<r){
int mid=l+(r-l)/3;
int midr=r-(r-l)/3;
if(f(mid,x)<f(midr,x)) l=mid+1;
else r=midr-1;
}
printf("%I64d\n",max(f(l,x),f(r,x)));
}
}
return 0;
}