【JZOJ NOIP2019模拟2019.9.4】A

16 篇文章 0 订阅

Description

在这里插入图片描述

Input

在这里插入图片描述

Output

在这里插入图片描述

Sample Input

2 4
3 0
4 -2
-1
0
1
2

Sample Output

6
0
3
12

Data Constraint

在这里插入图片描述

思路

由于没有常数项,所以可以同时除以x,式子变成:y=ax+b

对于x>0二分一个上凸壳

对于x《0二分一个下凸壳

代码

#include <bits/stdc++.h>
using namespace std;
#define pii pair <int,int>
#define LL long long
const int N = 6e5;
int n,q;
pii Eu[N],Ed[N],Su[N],Sd[N];
int cntu,cntd;
void work(pii E[],int n,pii S[],int &cnt)
{
    sort(E + 1,E + n + 1);
    for (int i = 1; i <= n; ++ i)
    {
        while (
            cnt >= 1 && S[cnt].first == E[i].first ||
            cnt >= 2 &&
                1ll * (S[cnt - 1].second - S[cnt].second) * (E[i].first - S[cnt - 1].first) >=
                1ll * (S[cnt - 1].second - E[i].second) * (S[cnt].first - S[cnt - 1].first))
                cnt --;
        S[++ cnt] = E[i];
    }
}
int calc(pii a,int x)
{
    return a.first * x + a.second;
}
LL find_max(pii S[],int cnt,int x)
{
    int l = 1,r = cnt;
    while (l < r)
    {
        int m = (l + r) / 2;
        if (calc(S[m],x) > calc(S[m + 1],x))
            r = m;
        else l = m + 1;
    }
    return 1ll * calc(S[l],x) * x;
}
int main()
{
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
    scanf("%d%d",&n,&q);
    for (int i = 1; i <= n; ++ i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        Eu[i] = make_pair(a,b);
        Ed[i] = make_pair(-a,-b);
    }
    work(Eu,n,Su,cntu);
    work(Ed,n,Sd,cntd);
    while (q --)
    {
        int x;
        scanf("%d",&x);
        if (x == 0) puts("0");
        else if (x > 0) printf("%lld\n",find_max(Su,cntu,x));
        else printf("%lld\n",-find_max(Sd,cntd,x));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值