【JZOJ NOIP2019模拟2019.9.4】A

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));
    }
}
发布了703 篇原创文章 · 获赞 392 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/Eric1561759334/article/details/100586443